linux后台运行程序并终端输出重定向

832次阅读

程序后台命令方式

1.nohup
  nohup的作用是让提交的命令忽略 hangup 信号。

      格式:nohup command args

eg:

 nohup ./main > /tmp/webcrawler.log  2>&1 &

        mian 是自己服务器上可以运行的go 二进制文件,>  /tmp//webcrawler.log 是将标准输出重定向到此目录下的webcrawler.log文件中,2>&1表示标准错误也输出到文件中,最后一个 & 表示加到后台(脱离终端会终止,加上nohup则不会)

只输出错误信息到日志文件

nohup ./main >/dev/null 2>log &

什么信息也不要

nohup ./main >/dev/null 2>&1 &

2.disown
    如果有运行的程序未放进后台运行,可以尝试下面的方式。

ctrl+z  # 将程序挂起jobs# 查看作业号bg job_id  # 放到后台运行disown -h %job_id

3.screen
  Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换 。使用screen后其是是 init(PID为1)的子进程,不会受到HUP信号的影响。

screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]

-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 -S name -> 新建一个叫name的session
screen -dms name ->创建一个detach的session
screen -ls -> 列出当前所有的session
screen -r name -> 回到name这个session
screen -d name -> 远程detach某个session # CTRL-a d快捷键终端当前Session
screen -d -r name -> 结束当前session并回到name这个session
 

4.setsid
  属于第二种策略,进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响。

setsid  # setsessionidUsage: setsid[options] <program> [arguments ...]

Run a program in a new session.

Options:

 -c, --ctty     set the controlling terminal to the current one
 -w, --wait     wait program to exit, and use the same return
 -h, --help     display this help and exit
 -V, --version  output version information and exit

后台运行时常用到的任务管理命令

1.jobs      

   查看任务,返回任务编号n和进程号。
   jobs -l 选项 可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated。但是如果任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识。

2.bg  %n   

     将编号为n的任务转后台运行

3.fg  %n   

       将编号为n的任务转前台运行

4.ctrl+z    

       挂起当前任务

5.ctrl+c    

       结束当前任务

标准输出和错误输出

shell中可能经常能看到:1>/dev/null  2>&1 

eg:

 sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print $4}'` 1>/dev/null 2>/dev/null

命令的结果可以通过%>的形式来定义输出

/dev/null 代表空设备文件
> 代表重定向到哪里,例如:echo “123” > /home/123.txt
1 表示stdout标准输出,系统默认值是1,所以”>/dev/null”等同于”1>/dev/null”
2 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
那么本文标题的语句:
1>/dev/null 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
2>&1 接着,标准错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

脚本只使用标准输入、标准输出和标准错误
     Shell会自动为我们打开和关闭0、1、2这三个文件描述符,我们不需要显式地打开或关闭它们。标准输入是命令的输入,默认指向键盘;标准输出是命令的输出,默认指向屏幕;标准错误是命令错误信息的输出,默认指向屏幕。
    如果没有显式地进行重定向,命令通过文件描述符0从屏幕读取输入,通过文件描述符1和2将输出和错误信息输出到屏幕。但如果我们想从其他文件(再次强调,I/O设备在Unix/Linux中也是文件)读取输入或产生输出,就需要对0、1、2使用重定向了。其语法如下:

command < filename                   把标准输入重定向到filename文件中command 0< filename                  把标准输入重定向到filename文件中command > filename                   把标准输出重定向到filename文件中(覆盖)command 1> fielname                  把标准输出重定向到filename文件中(覆盖)command >> filename                  把标准输出重定向到filename文件中(追加)command 1>> filename                 把标准输出重定向到filename文件中(追加)command 2> filename                  把标准错误重定向到filename文件中(覆盖)command 2>> filename                 把标准输出重定向到filename文件中(追加)command > filename 2>&1              把标准输出和标准错误一起重定向到filename文件中(覆盖)command >> filename 2>&1             把标准输出和标准错误一起重定向到filename文件中(追加)command < filename >filename2        把标准输入重定向到filename文件中,把标准输出重定向                                     到filename2文件中command 0< filename 1> filename2     把标准输入重定向到filename文件中,把标准输出重定向到                                      filename2文件中

重定向的使用有如下规律:
1)标准输入0、输出1、错误2需要分别重定向,一个重定向只能改变它们中的一个。
2)标准输入0和标准输出1可以省略。(当其出现重定向符号左侧时)
3)文件描述符在重定向符号左侧时直接写即可,在右侧时前面加&。
4)文件描述符与重定向符号之间不能有空格!

1. 标准输入的控制
语法:命令< 文件将文件做为命令的输入。
例如:

mail -s “mail test” [email protected] < file1 

     将文件file1 当做信件的内容,主题名称为mail test,送给收信人。
2. 标准输出的控制
语法:命令> 文件将命令的执行结果送至指定的文件中。
例如:

ls -l > list 

将执行“ls -l”  命令的结果写入文件list 中。

语法:命令>! 文件将命令的执行结果送至指定的文件中,若文件已经存在,则覆盖。
例如:

ls -lg >! list 

  将执行“ls – lg” 命令的结果覆盖写入文件list 中。

语法:命令>& 文件将命令执行时屏幕上所产生的任何信息写入指定的文件中。
例如:

cc file1.c >& error 

 将编译file1.c 文件时所产生的任何信息写入文件error 中。

语法:命令>> 文件将命令执行的结果附加到指定的文件中。
例如:
 

ls - lag >> list 

将执行“ls – lag” 命令的结果附加到文件list 中。

语法:命令>>& 文件将命令执行时屏幕上所产生的任何信息附加到指定的文件中。
例如:
cc file2.c >>& error

ls - lag >> list 

将编译file2.c 文件时屏幕所产生的任何信息附加到文件error 中。

3)关于输入、输出和错误输出
       在字符终端环境中,标准输入/标准输出的概念很好理解。输入即指对一个应用程序或命令的输入,无论是从键盘输入还是从别的文件输入;输出即指应用程序或命令产生的一些信息;与 Windows 系统下不同的是,Linux 系统下还有一个标准错误输出的概念,这个概念主要是为程序调试和系统维护目的而设置的,错误输出于标准输出分开可以让一些高级的错误信息不干扰正常的输出信息,从而方便一般用户的使用。
       在 Linux 系统中:标准输入(stdin)默认为键盘输入;标准输出(stdout)默认为屏幕输出;标准错误输出(stderr)默认也是输出到屏幕(上面的 std 表示 standard)。在 BASH 中使用这些概念时一般将标准输出表示为 1,将标准错误输出表示为 2。下面我们举例来说明如何使用他们,特别是标准输出和标准错误输出。
      输入、输出及标准错误输出主要用于 I/O 的重定向,就是说需要改变他们的默认设置。

例如:

ls > ls_resultls -l >> ls_result

       上面这两个命令分别将 ls 命令的结果输出重定向到 ls_result 文件中和追加到 ls_result 文件中,而不是输出到屏幕上。”>”就是输出(标准输出和标准错误输出)重定向的代表符号,连续两个 “>” 符号,即 “>>” 则表示不清除原来的而追加输出。下面再来看一个稍微复杂的例子:

 find /home -name lost* 2> err_result

       这个命令在 “>” 符号之前多了一个 “2”,“2>” 表示将标准错误输出重定向。由于 /home 目录下有些目录由于权限限制不能访问,因此会产生一些标准错误输出被存放在 err_result 文件中。可以设想一下 find /home -name lost* 2>>err_result 命令会产生什么结果?
      如果直接执行 find /home -name lost* > all_result ,其结果是只有标准输出被存入 all_result 文件中,要想让标准错误输出和标准输入一样都被存入到文件中,那该怎么办呢?看下面这个例子:

 find /home -name lost* > all_result 2>& 1

      上面这个例子中将首先将标准错误输出也重定向到标准输出中再将标准输出重定向到 all_result 这个文件中。这样我们就可以将所有的输出都存储到文件中了。为实现上述功能,还有一种简便的写法如下:

find /home -name lost* >& all_result

    如果那些出错信息并不重要,下面这个命令可以避开众多无用出错信息的干扰:

find /home -name lost* 2> /dev/null

可以自己试验一下如下几种重定向方式:

find /home -name lost* > all_result 1>& 2find /home -name lost* 2> all_result 1>& 2find /home -name lost* 2>& 1 > all_result

    另外一个非常有用的重定向操作符是 “-“

例如:

(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)

      该命令表示把 /source/directory 目录下的所有文件通过压缩和解压,快速的全部移动到 /dest/directory 目录下去,这个命令在 /source/directory 和 /dest/directory 不处在同一个文件系统下时将显示出特别的优势。
下面还几种不常见的用法:
n<&- 表示将 n 号输入关闭
<&- 表示关闭标准输入(键盘)
n>&- 表示将 n 号输出关闭
>&- 表示将标准输出关闭 
 
例子:

make >& compile.log 

   将编译u-boot时屏幕产生的所有信息重定向到compile.log文件中;

make > compile.log 2>&1

       首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到 compile.log 这个文件中。这样我们就可以将所有的输出都存储到文件中了。
 

make  2> compile.log

       将标准出错输出信息写入compile.log,但标准输出则在屏幕上显示。此时屏幕上不显示编译时的错误信息,这些信息将写入compile.log中;
 

make  1> compile.log  

     将标准输出信息写入compile.log,但标准出错输出则在屏幕上显示。此时屏幕上不显示编译时的正确信息,这些信息将写入compile.log中。

echo "pls enter the para" >&2

    把你的错误交给标准错误

正文完