输入输出重定向
重定向分为输入重定向与输出重定向。所谓的输入重定向即输入不从键盘读入,而是从文件输入或其它。
所谓的输出重定向即不输出到终端上,而是输出到文件中去或其它。
""<"表示输入重定向运算符
$ wc composer.json
86 159 2526 composer.json
> 是定向输出到文件,如果文件不存在,就创建文件;如果文件存在,就将其清空;一般我们备份清理日志文件的时候,就是这种方法:先备份日志,再用`>`,将日志文件清空(文件大小变成0字节);请检查您是否具有写入指定文件的权限。您可以使用chmod命令更改文件的权限。
>>这个是将输出内容追加到目标文件中。如果文件不存在,就创建文件;如果文件存在,则将新的内容追加到那个文件的末尾,该文件中的原有内容不受影响。
echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile
用途:nohup表示永久运行。&表示后台运行(异步)在应用Unix/Linux时,我们一般想让某个程序在后台运行 该命令的一般形式为:
nohup command &
php bin/console oss:bill > /var/log/oss.log 2>&1 &
前后台进程
linux进程是区分前台进程和后台进程的。
通常,在终端输入的命令执行的前台进程模式。如果一个命令要执行好久,就会阻塞住终端好久,不能进行其他工作,所以,我们可以把执行花费时间很长的任务使用后台进程模式运行,我们就可以在同一终端干其他事
#!/bin/bash
start_date=20210801
end_date=20210831
start_sec=`date -d "$start_date" "+%s"`
end_sec=`date -d "$end_date" "+%s"`
for(i=start_sec;i<=end_sec;i+=86400)); do
day=$(date -d "@$i" "+%Y-%m-%d")
php bin/console month_bill --date=$day &
done
上面的程序如果没有&,按照天执行脚本,等待执行完毕后才循环下一个,只有一个进程。加&后循环产生31个进程,不需要阻塞等待每天的脚本执行完毕。
查看后台任务
[root@localhost cdnjs]# jobs
[1]+ 已停止 find / -name xml
前台切后台
在运行命令后,有的时候忘记了在命令之后加上‘&’符号,又不愿意停下此命令重新改写。这是可以按[ctrl+z],把当前程序切入后台。
但是要注意此时在后台的这个程序是处于 Stopped 状态
要继续执行的话,先使用jobs命令找出当前任务的jobId,然后按如下操作
[root@localhost cdnjs]#bg 1
后台切回前台
先使用jobs命令找出当前任务的jobId,然后按如下操作
[root@localhost cdnjs]#fg 1
在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:
nohup command > myout.file 2>&1 &
在上面的例子中,输出被重定向到myout.file文件中。类似XShell终端输出的历史记录有一定的限制,记录过多,就会丢失掉之前的输出内容。用输出重定向能很好的解决这个问题。
shell中可能经常能看到:>/dev/null 2>&1 我们将这个命令组合:“>/dev/null 2>&1” 拆为四部分来分析下:
- 首先 0> 表示stdin标准输入; 1> 表示stdout标准输出; 2> 表示stderr错误输出;
- 符号 > 等价于 1> (系统默认为1,省略了先); 所以">/dev/null"等同于 "1>/dev/null"
- /dev/null 代表空设备文件
- & 可以理解为是"等同于"的意思,2>&1,即表示2的输出重定向等同于1。因此,>/dev/null 2>&1 也可以写成“1> /dev/null 2> &1”
nohup和&的功效。
使用&后台运行程序:
-
结果会输出到终端
-
使用Ctrl + C发送SIGINT信号,程序免疫
-
关闭session发送SIGHUP信号(退出SSH连接),程序关闭
使用nohup运行程序:
-
结果默认会输出到nohup.out
-
使用Ctrl + C发送SIGINT信号,程序关闭
-
关闭session发送SIGHUP信号,程序免疫
平日线上经常使用nohup和&配合来启动程序:
-
同时免疫SIGINT和SIGHUP信号
tee命令
在输出信息的同时把信息记录到文件中
ls | tee /data/www/html/ls.log
Screen
在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。Screen实现了基本的文本操作,如复制粘贴等;还提供了类似滚动条的功能,可以查看窗口状况的历史记录。窗口还可以被分区和命名,还可以监视后台窗口的活动。 会话共享 Screen可以让一个或多个用户从不同终端多次登录一个会话,并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保护。
$sudo apt-get intstall screen
yum install screen
screen会话默认是用进程号.终端号.主机名来命名的,如果同时打开多个会话的话,真是一头包。
切换到一个新的窗口
screen
让进程在后台执行,回到原窗口
ctrl + A + D
直接杀掉一个screen
screen -S screenID -X quit
[root@localhost ~]# screen -ls
There is a screen on:
41493.pyapi (Detached)
1 Socket in /var/run/screen/S-root.
[root@localhost ~]# screen -S 41493.pyapi -X quit
[root@localhost ~]# screen -ls
No Sockets found in /var/run/screen/S-root.
查看当前所有进程
screen -ls
回到指定进程
screen -r 41493(进程号)
screen -S my_screen_name 修改会话名称
ctrl+a k 终止当前进程
如果他的状态是Detached的,我们需要输入screen -r <screen的pid> ,来进入这个screen ,或者screen -rd <screen的名称> ;
如果他的状态是Attached的,我们就要输入 screen -d <screen的pid> ,来使他”Dettached”,然后再输入screen -r <screen的pid>,来进入这个screen。(必须先detached,否则是进入去的)。
Screen命令的常规用法:
-A 将所有的视窗都调整为目前终端机的大小。
-d <作业名称> 将指定的screen作业离线。
-h <行数> 指定视窗的缓冲区行数。
-m 即使目前已在作业中的screen作业,仍强制建立新的screen作业。
-r <作业名称> 恢复离线的screen作业。
-R 先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s 指定建立新视窗时,所要执行的shell。
-S <作业名称> 指定screen作业的名称。
-v 显示版本信息
-x 恢复之前离线的screen作业。
-ls或--list 显示目前所有的screen作业。
-wipe 检查目前所有的screen作业,并删除已经无法使用的screen作业。
screen -D -r:连接一个screen进程,如果该进程是attached,就先踢掉远端用户并让他logout再连接
screen -m:如果在一个Screen进程里,用快捷键crtl+a c或者直接打screen可以创建一个新窗口,screen -m可以新建一个screen进程。
screen -dm:新建一个screen,并默认是detached模式,也就是建好之后不会连上去。
screen -p number or name:预先选择一个窗口。
Screen命令中用到的快捷键
Ctrl+a c :创建窗口
Ctrl+a w :窗口列表
Ctrl+a n :下一个窗口
Ctrl+a p :上一个窗口
Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换
Ctrl+a K(大写) :关闭当前窗口,并且切换到下一个窗口(当退出最后一个窗口时,该终端自动终止,并且退回到原始shell状态)
exit :关闭当前窗口,并且切换到下一个窗口(当退出最后一个窗口时,该终端自动终止,并且退回到原始shell状态)
Ctrl+a d :退出当前终端,返回加载screen前的shell命令状态
解决 screen 中文乱码,及screen基本用法
找到screenrc文件(通过whereis screenrc)添加以下配置
defutf8 on
defencoding utf8
encoding UTF-8 UTF-8
如何用bash脚本创建screen并向其发送命令
#先关闭screen
screen -S $screen_name -X quit
#重开detached screen
screen -dmS $screen_name
cmd=$"bash /tmp/task.sh";
screen -x -S $screen_name -p 0 -X stuff "$cmd" # 输入命令
screen -x -S $screen_name -p 0 -X stuff $'\n' # "回车"的操作用于执行命令
#screen -x -S $screen_name -p 0 -X stuff "$cmd \n"
注意
这种方式发送的命令不能太长,否则会导致脚本卡住。如果需要发送一条很长的命令,或者连续发送许多条命令,最好单独写一个脚本,发送一个脚本命令给screen,让screen执行新的脚本。
screen设置窗口标题
caption always "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%H %Y/%m/%d "
杀死所有 screen 任务
1、先看看有多少个screen
screen -ls |awk '/Socket/'|awk '{print $1}'
2、如果有 N 个screen,关闭所有screen
screen -ls|awk 'NR>=2&&NR<=N{print $1}'|awk '{print "screen -S "$1" -X quit"}'|sh