前置条件
- 一台 linux 或 windows 服务器
- 会使用 linux 和 windows 下的终端(windows 得安装支持 bash 的终端)
内容主体
常见的 linux 目录含义
| 目录 | 用途 |
|---|---|
| / | 根目录 |
| /bin | 二进制目录,存放用户级的 GNU 工具 |
| /boot | 启动目录,存放启动文件 |
| /dev | 设备目录,linux 在这里创建设备节点 |
| /etc | 系统配置文件 |
| /home | 主目录,linux 在这里创建用户目录 |
| /lib | 库目录,存放系统和应用程序的库文件 |
| /media | 媒体目录,可移动媒体设备的常用挂载点 |
| /nmt | 挂载目录,另一个可移动媒体设备的常用挂载点 |
| /opt | 可选目录,常用于存放第三方软件包和数据文件 |
| /proc | 进程目录,存放现有硬件及当前进程的相关信息 |
| /root | root 用户的主目录 |
| /sbin | 系统二进制目录,存放许多 GNU 管理员级工具 |
| /run | 运行目录,存放系统运作时的运行时数据 |
| /srv | 服务目录,存放本地服务的相关文件 |
| /sys | 系统目录,存放系统硬件信息的相关文件 |
| /tmp | 临时目录,可以在该目录中创建和删除临时工作文件 |
| /usr | 用户二进制目录,大量用户级的 GNU 工具和数据文件都存储在这里 |
| /var | 可变目录,用以存放经常变化的文件,比如日志文件 |
目录命令
显示所有文件(区分文件夹与文件)
ls -F
显示文件或文件夹的详细信息(权限、用户组、文件类型)
ll
搜索目录下 content
ll *t?nt
创建目录
mkdir folder
复制目录
cp -R souce destination
删除目录
rmdir folder
rm -rf folder
显示目录树
tree folder
文件命令
创建
touch 1.txt
复制
cp -R source destination
重命名
mv from to
删除
rm -i file
查看文件内容类型
file fileExample
查看部分文件
more file
tail file
进程命令
显示当前所有进程
ps -ef
- -e 参数指定所有运行在系统上的进程
- -f 参数扩展输出的进程消息
UID: 启 动 这 些 进 程 的 用 户。
PID: 进 程 的 进 程 ID。
PPID: 父 进 程 的 进 程 号( 如 果 该 进 程 是 由 另 一 个 进 程 启 动 的)。
C: 进 程 生 命 周 期 中 的 CPU 利 用 率。
STIME: 进 程 启 动 时 的 系 统 时 间。
TTY: 进 程 启 动 时 的 终 端 设 备。
TIME: 运 行 进 程 需 要 的 累 计 CPU 时 间。
CMD: 启 动 的 程 序 名 称。
结束进程
kill pid
kill -s pid # 强制关闭
killall 进程名 # 关闭进程名的所有进程
父子shell
进程列表,用 () 表示子 shell
(pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls ; echo $ BASH_SUBSHELL)
变量
设置变量
echo $my_variable
my_variable = Hello #变量赋值
echo $my_variable #打印变量
unset my_variable #删除变量
yum 软件安装管理
列出已经安装的包
yum list installed
安装软件
yum install package_name
更新软件
yum update package_name
yum updates
卸载软件
yum remove package_name #保留数据和配置文件
yum erase package_name #删除软件和配置文件
手动安装软件
#下载tar
tar -zxvf tar包
make
make install
Vim 编辑器
快捷键
:set nu #打开行号
:set nonu #隐藏行号
G #移到最后一行
gg #移动到第一行
dd #删除当前行
d5d #删除光标后5行
p #粘贴到某地
/值 #查找
Shell 基础
创建 shell 脚本文件
#!/bin/bash
#文件开头
date
who
用户变量
name=william #注意 = 之间不能有空格
value1=10
value2=$value1
命令输出给变量
test=`date`
test=$(date)
date +%y%m%d #201125
输出重定向
who > 123.txt # 创建或覆盖原有内容
who >> 123.txt # 追加内容
输入重定向
wc < 123.txt #输出 行数、词数、字节数
wc << EOF #内联输入重定向,只需要在对内联输入的提供
> test 1
> test 2
> test 3
>EOF # 输入结束符
管道
ls | more
整数运算
var1 = 100
var2 = 45
var3 = $[ $var1 / $var2]
输出 2
浮点运算
#!/bin/bash
var1=100
var2=45
var3=$( echo "scale = 4; $var1/$var2" | bc)
echo The answer for this is $ var3
输出:2.2222
退出脚本
echo $? # 查看退出状态 0为成功
# 退出码 0~255
exit 5
结构化语句
if-then 语句
if pwd #pwd 命令返回 0 则执行then
then echo "It worked"
fi
if-then-else 语句
if command
then command
else command
fi
嵌套 if
if command
then command
else
if command
then command
fi
fi
elif
if command1
then
commands
elif command2 #状态码为0则执行then中语句
then
more commands
fi
test 命令
test condition
if test condition #
then
echo "No expression returns a True"
else
echo "No expression returns a False"
fi
条件 [ ]
if [ $num -gt 2 ]
then
echo "True"
else
echo "False"
fi
[ ] 也可以进行字符串比较
str1=name
str2=sex
[ $str1 = $str2 ]
[ $str1 \> $str2 ] #转义大写
str1=william
str2=''
[ -n $str1 ]
#判 断 str1 变 量 是 否 长 度 非 0, 而 它 的 长 度 正 好 非 0, 所 以 then 部 分 被 执 行 了。
[ -z $str2 ]
#判 断 str1 变 量 是 否 长 度 为 0, 而 它 的 长 度 正 好 为 0, 所 以 then 部 分 被 执 行 了。
文件比较
-d file 检 查 file 是 否 存 在 并 是 一 个 目 录
-e file 检 查 file 是 否 存 在
-f file 检 查 file 是 否 存 在 并 是 一 个 文 件
-r file 检 查 file 是 否 存 在 并 可 读
-s file 检 查 file 是 否 存 在 并 非 空
-w file 检 查 file 是 否 存 在 并 可 写
-x file 检 查 file 是 否 存 在 并 可 执 行
-O file 检 查 file 是 否 存 在 并 属 当 前 用 户 所 有
-G file 检 查 file 是 否 存 在 并 且 默 认 组 与 当 前 用 户 相 同
file1 -nt file2 检 查 file1 是 否 比 file2 新
file1 -ot file2 检 查 file1 是 否 比 file2 旧
检查目录是否存在 -d
#!/bin/bash
jump_directory=/home/shell
if [ -d $jump_directory ]
then
echo "The $jump_directory directory exists"
cd $jump_directory
ls
else
echo "The $jump_directory directory does not exist"
fi
检查对象是否存在-e
#!/bin/bash
location=$HOME
file_name="123"
if [ -e $location ]
then
echo "OK on the $location directory."
echo "Now checking on the file, $file_name."
if [ -e $location/$file_name ]
then
echo "Ok on the filename"
echo "Updating current Date"
date >> $location/$file_name
else
echo "File does not exist"
echo "Nothing to update"
fi
else
echo "The $location directory does not exist."
echo "Nothing to update"
fi
复合条件
if-then 语句中加入复合条件
[ condition1 ] && [ condition2 ]
[ condition1 ] | | [ condition2 ]
使用双括号 (())
val1=10
if (( $val1**2>90 ))
then
(( val2=$val1**2 ))
echo "The square of $val1 is $val2"
fi
case 命令
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
循环
for 循环
for var in list
do commands
done
例子
for test in Alabama Alaska Arizona Arkansas California Colorado
do echo The next state is $ test
done
拼接list
list="Alabama Alaska Arizona Arkansas Colorado"
list=$list" 123"
for state in $list
do echo "Have you ever visited $state?"
done
从命令中读取列表
file=`pwd`
for state in $( ls $file) #ls、cat等
do echo "Visit beautiful $state"
done
内部字段分隔符
file=`pwd`
IFS=$'\n' #告 诉 bash shell 在 数 据 值 中 忽 略 空 格 和 制 表 符。采用换行符分割list
IFS=: #用:分号分割列表
IFS = $'\ n':;" #多个 IFS 值
for state in $( ls $ file)
do echo "Visit beautiful $state"
done
使用通配符读取目录
mulu=/home/*
for file in $mulu
do
if [ -d "$file" ]
then echo "$file is a directory"
elif [ -f "$file" ]
then echo "$file is a file"
fi
done
C 语言类型的 for 循环
for (( i=1; i <= 10; i ++ ))
do echo "The next number is $i"
done
while 命令
while test command
do other commands
done
while [ $var1 -gt 0 ] #迭代条件必须能够跳出,否则进入死循环
var1 = $[ $var1 - 1 ]
while 使用多个测试命令
var1=10
while echo $var1
[ $var1 -ge 0 ]
do
echo "This is inside the loop"
var1=$[ $var1 - 1 ]
done
util 命令
until test commands #一旦测试命令返回了0状态码,则不再执行 do 方法
do other commands
done
var1=100
until [ $var1 -eq 0 ]
do echo $var1
var1=$[ $var1 - 25 ]
done
循环控制
break #跳出内部循环,外部循环仍在运行
continue #符合某个条件,直接进入下一次循环
循环的输出重定向到文件
done -> output.txt #循环的输出直接到哦 output.txt 命令中
得到可在命令行中可执行文件的列表
IFS=:
for folder in $PATH
do
echo "$ folder:"
for file in $folder/*
do
if [ -x $file ]
then
echo " $file"
fi
done
done
Shell 循环案例
从 .csv 读取文件
input="users.csv"
while IFS=',' read -r userid name
do
echo "adding $userid"
useradd -c "$name" -m $userid
done < "$input"
#user.csv内容
users.csv
rich, Richard Blum
christine, Christine Bresnahan
barbara, Barbara Blum
tim, Timothy Bresnahan
处理用户输入
读取参数
total=$[ $1 * $2 ]
echo The first parameter is $1.
cho The second parameter is $2.
echo The total value is $total.
./ test2. sh 2 5
The first parameter is 2.
# 若参数中包含空格必须使用单引号或双引号
获取当前运行的脚本名
name=$( basename $0)
echo
echo The script name is: $name
The script name is: test5b.sh
获取当前输入参数的数量
echo There were $# parameters supplied. # $# 含有脚本运行时携带的命令行参数的个数。
echo this is $2 parameters # $2 表示输入的第二个变量
# 你 不 能 在 花 括 号 内 使 用 美 元 符。 必 须 将 美 元 符 换 成 感 叹 号。
# 获取输入变量的最后一个变量
echo The last parameter is ${!#}
一次获取所有参数
count=1
for param in "$*"
do
echo "\$* Parameter #$count=$param"
count=$[ $count + 1 ]
done
####################################################
count=1
for param in "$@"
do
echo "\$@ Parameter #$count=$param"
count=$[ $count + 1 ]
done
处理选项
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option" ;;
-c) echo "Found the -c option" ;;
*) echo "$1 is not an option" ;;
esac
shift
done
# shift 命 令 时, 默 认 情 况 下 它 会 将 每 个 参 数 变 量 向 左 移 动 一 个 位 置。 所 以, 变 量 $ 3 的 值 会 移 到 $ 2 中, 变 量 $ 2 的 值 会 移 到 $ 1 中, 而 变 量 $ 1 的 值 则 会 被 删 除( 注 意, 变 量 $ 0 的 值, 也 就 是 程 序 名, 不 会 改 变)。
分 离 参 数 和 选 项
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option";;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
count=1
for param in $@
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
用户输入
echo -n "Enter your name: "
read name
echo "Hello $name, welcome to my program. "
#####################
read -p "Please enter your age: " age
days=$[ $age * 365 ]
echo "That makes you over $days days old! "
实际应用
windows 平台下的 jar 包一键启动脚本
@echo off
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_261
set APP_HOME=D:\sqjzService
set PROFILE=dev
set JVM_XMS=1g
set JVM_XMX=4g
set PORT=7788
title sqjzService_%PORT%
set classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%lib\tools.jar;
set path=%JAVA_HOME%\bin
java -Xms%JVM_XMS% -Xmx%JVM_XMX% -jar %APP_HOME%\sqjzService.jar --spring.profiles.active=%PROFILE% > %APP_HOME%/logs/batchLog%date:~0,4%%date:~5,2%%date:~8,2%.log
@pause
目录结构
./
logs/
sqjzService.jar
start.bat
start.sh
stop.bat
stop.sh
Linux 系统下 jar 包启动脚本
#!/bin/bash
JAVA_HOME=/opt/java/jdk1.8.0_144
APP_HOME=/opt/jar/sqjzService
PROFILE=prod
JVM_XMS=1g
JVM_XMX=4g
nohup $JDK/java -Xms$JVM_XMS -Xmx$JVM_XMX -jar $APP_HOME/sqjzService.jar \
--spring.profiles.active=$PROFILE \
>/dev/null 2>&1 &
windows 下一键关闭脚本
@echo off
set PORT=7788
for /f "tokens=5" %%i in ('netstat -ano^|findstr ":%PORT%"') do (
echo kill the process %%i who use the port %port%
taskkill /pid %%i -t -f
)
linux 下一键关闭脚本
#!/bin/bash
APP=sqjzService
pid=`ps -ef | grep $APP.jar | grep -v grep | awk '{print $2}'`
if [ -n "$pid" ]
then
kill -9 $pid
fi