让命令在后台执行
我们在测试时,经常会需要命令在后台执行,这样就算终端窗口关闭了,命令依然能在后台运行,其实有多种方法能达到目的,我把我经常用到的两种方法记录一下。
方式一:
/usr/bin/setsid watch ceph -s
setsid的作用是将命令放在后台执行,这样即使终端退出了也不会影响命令继续执行,但是这有个不好的地方就是咱们要查看这个命令的执行情况时,没法查看,所以这种方式适合那种后台运行后不需要再去查看命令执行情况时使用。
方式二:
使用screen工具,安装screen命令:
yum install screen ##CentOS系统 apt-get install screen ##Debian/Ubuntu系统
创建一个新窗口(守护模式):
screen -dmS vdbench ## 在后台创建一个新窗口,不进入窗口
创建一个新窗口:
screen -S vdbench
从当前窗口中离开:
ctrl+a d ##先按下ctrl+a,再按d
查看当前正在运行的窗口id号和名称:
screen -ls
进入指定窗口:
screen -r 18813 ##18813是指定窗口会话的id号,也可以使用名称,但是当有多个一样的名称时,会提示有相同的名称存在,而id号确是唯一的
在当前窗口关闭当前窗口:
ctrl+d
在未进入指定窗口时关闭指定窗口:
screen -X -S 28476 quit ##28476是指定窗口会话的id号
发送指定的命令到指定窗口并执行:
cmd=$"pwd" ##要输入的命令行 screen -x -S $screen_name -p 0 -X stuff "$cmd" ##-S后面是指定出窗口会话的名称或ID,-p后面的0表示如果会话名称存在就选择编号为0的窗口,-X stuff "$cmd"表示将$cmd字符串命令发送到窗口中 screen -x -S $screen_name -p 0 -X stuff $'\n' ## -X stuff $'\n'表示执行回车,在脚本中执行时要去掉$号
注意
这种方式发送的命令不能太长,否则会导致脚本卡住。
如果需要发送一条很长的命令,或者连续发送许多条命令,最好单独写一个脚本,发送一个脚本命令给screen,让screen执行新的脚本。
使用screen工具的好处除了能在终端断开的情况下命令能继续在后台执行外,另外一个好处就是在想查看命令执行的情况时可以随时查看,比如我们在使用vdbench工具测试集群稳定性的时候,开启一个新窗口让vdbench在新窗口里面跑,然后按下ctrl+a d 离开窗口,就可以关闭终端窗口了,在想看vdbench执行情况时再进入到这个新窗口里面,就可以实时查看当前运行的情况,很方便。
实例1(创建一个screen窗口并自动执行指定命令):
1 #!/bin/bash 2 screen_name=$1 3 if screen -ls|grep $screen_name;then 4 echo "名称为$screen_name的screen窗口已存在,10秒后开始打印vdbench日志。" 5 else 6 screen -dmS $screen_name 7 cmd=$"cd /root/vdbench50406/;./vdbench -f test_config" 8 screen -x -S $screen_name -p 0 -X stuff "${cmd}" 9 screen -x -S $screen_name -p 0 -X stuff $'\n' 10 fi 11 sleep 10 12 tailf /root/vdbench50406/output/logfile.html
实例2(使用screen实现使用scp拷贝文件或目录时免确认和自动输入密码):
#!/bin/bash file=$1 if [ -z "$file" ]; then echo "Usage: $0 file" exit 1 fi # 检查是否为文件或目录 if [ -f "$file" ] || [ -d "$file" ]; then true else echo "File $file does not exist or is not a file or directory." exit 1 fi # 判断文件类型,设置变量cmd if [ -f "$file" ]; then cmd=$"scp -o StrictHostKeyChecking=no $file 192.168.30.115:/root" elif [ -d "$file" ]; then cmd=$"scp -o StrictHostKeyChecking=no -r $file 192.168.30.115:/root" fi passwd="123456" screen -ls | awk '/temp+/{print $1}'|awk '{print "screen -S "$1" -X quit"}' | sh screen -LdmS temp $cmd sleep 1 screen -x -S temp -p 0 -X stuff "${passwd}" screen -x -S temp -p 0 -X stuff $'\n' #echo "Start..." > screenlog.0 && tail -f screenlog.0 echo "Start..." > screenlog.0 tail -f screenlog.0 | tee /dev/tty | sed -n "/.*100%.*/{ ekill -9 $(ps -ef | grep $$ | grep tail | awk '{print $2}') > /dev/null 2>&1 q }" echo "End."
效果:
[root@node116 ~]# sh test4.sh Usage: test4.sh file [root@node116 ~]# sh test4.sh s File s does not exist or is not a file or directory. [root@node116 ~]# sh test4.sh file1 Start... Warning: Permanently added '192.168.30.115' (ECDSA) to the list of known hosts. root@192.168.30.115's password: file1 100% 7 2.9KB/s 00:00 End. [root@node116 ~]# sh test4.sh test1 Start... root@192.168.30.115's password: chid_process.c 100% 1508 584.4KB/s 00:00 process.sh 100% 1067 450.8KB/s 00:00 chid_process 100% 8824 397.2KB/s 00:00 handler_process.c 100% 478 204.8KB/s 00:00 handler_process 100% 8640 3.3MB/s 00:00 End. [root@node116 ~]#