别忘了在disown之前执行bg命令,否则进程会一直stopped

本文分享了一次在Linux环境下让程序在后台持续运行的经验教训。作者通过实例演示了如何使用bg命令使暂停的程序继续运行,再使用disown命令将其从当前终端分离,避免因关闭终端导致程序停止。强调了在使用disown前必须先用bg命令恢复程序运行状态的重要性。

别忘了在disown之前执行bg命令,否则进程会一直stopped

今天在Linux下测试程序,是直接执行的命令,如下所示:

[root@NODE22 bin]# ./cap
#======= CAP v20120216f =======#
prog-path: /root/work22/ct08/bin/
prog-name: cap
cfg_name='../cfg/cap.cfg'
loadconfig ok
checkconfig ok
System::Init ok
cap start ok, pid 8342

想到这个程序要在我下班之后继续执行,于是我就按下了Ctrl+Z

 


[1]+  Stopped                 ./cap

 

因为我准备关闭SecureCRT准备收工了,所以决定让它脱离我这个终端,执行了disown来做这件事

[root@NODE22 bin]# disown %1
-bash: warning: deleting stopped job 1 with process group 8342
[root@NODE22 bin]#

 

看看这个操作灵不灵,我看了一下日志,发现日志没有继续往下记录,正常情况应该往下记录的。

 

想起来,没有在disown之前执行bg命令,程序已经处于Stopped状态(看disown命令的输出),得让它继续往下执行

 

[root@NODE22 bin]# killall -CONT cap

 

日志也正常了。切记啊,切记啊:别忘了在disown之前执行bg命令

 

 

本文地址: http://codingstandards.iteye.com/blog/1408321

 

 

相关帮助信息:

[root@NODE22 eap_designer]# help disown
disown: disown [-h] [-ar] [jobspec ...]
    By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
[root@NODE22 eap_designer]# help bg
bg: bg [job_spec ...]
    Place each JOB_SPEC in the background, as if it had been started with
    `&'.  If JOB_SPEC is not present, the shell's notion of the current
    job is used.
[root@NODE22 eap_designer]# help fg
fg: fg [job_spec]
    Place JOB_SPEC in the foreground, and make it the current job.  If
    JOB_SPEC is not present, the shell's notion of the current job is
    used.
[root@NODE22 eap_designer]# help jobs
jobs: jobs [-lnprs] [jobspec ...] or jobs -x command [args]
    Lists the active jobs.  The -l option lists process id's in addition
    to the normal information; the -p option lists process id's only.
    If -n is given, only processes that have changed status since the last
    notification are printed.  JOBSPEC restricts output to that job.  The
    -r and -s options restrict output to running and stopped jobs only,
    respectively.  Without options, the status of all active jobs is
    printed.  If -x is given, COMMAND is run after all job specifications
    that appear in ARGS have been replaced with the process ID of that job's
    process group leader.
[root@NODE22 eap_designer]#

 

 

 

<think>我们已知用户意图是:如何在执行命令时不显示在'w'命令的WHAT列中。 根据引用[1]中关于w命令的说明,w命令会显示当前登录用户的活动,包括WHAT列,该列显示用户当前正在执行命令。 要避免命令显示在WHAT列,我们需要使得命令执行时不被w命令捕获。通常,w命令通过检查进程命令行参数来获取信息,因此,如果我们能够使得进程命令行参数不显示具体的命令,就可以达到隐藏的效果。 一种常见的方法是使用shell的别名(alias)功能,将命令重命名为一个不敏感的名字,但这并不能完全隐藏,因为进程名可能还是会被显示。 另一种更有效的方法是使用exec命令来替换当前shell进程,这样在进程列表中显示的是新的进程名,而不是原来的命令。 具体做法是:使用一个包装脚本,该脚本通过exec来执行目标命令,这样在进程列表中,原来的shell进程被替换为目标命令,而包装脚本本身在执行exec后就已经退出了,因此不会出现在进程列表中。但是,这只能改变进程名,而w命令的WHAT列通常显示的是命令行参数,所以我们需要控制命令行参数。 然而,更直接的方法是使用一个中间程序,它能够修改自己的argv[0](即程序名称)。我们可以编写一个C程序,通过execve系统调用执行目标命令,并在执行前修改argv[0]为其他字符串。 但是,用户可能希望一个简单的方法。实际上,在Linux中,我们可以使用以下技巧: 1. 使用括号开启一个子shell,并在子shell中执行命令,然后让子shell立即退出。这样,在w命令的WHAT列中,可能只会显示一个临时的子shell进程,而不会显示具体的命令。 2. 使用nohup命令命令放到后台执行,并且重定向输出,这样命令会脱离当前shell的会话,但w命令可能仍然会显示nohup命令。 实际上,更可靠的方法是利用一些特殊的shell特性。例如,在bash中,我们可以使用以下方法: (command >/dev/null 2>&1 &) 这样,命令会在子shell中后台运行,并且重定向了输出,然后子shell立即退出。在w命令中,我们可能会看到短暂的子shell进程,但很快消失,而命令本身在后台运行,其父进程变为init(进程ID为1),因此不会关联到当前登录会话。但是,w命令可能不会显示已经脱离终端的后台进程。 然而,根据w命令的机制,它显示的是与终端关联的进程。如果我们将命令放到后台并且脱离终端(比如使用disown),那么它就不会出现在w命令的WHAT列中。 具体步骤: 1. 执行命令时,在命令末尾加上`&`将其放入后台。 2. 使用`disown`命令将该作业从当前shell的作业表中移除,这样即使shell退出,命令也不会收到SIGHUP信号,并且与当前终端脱离。 3. 这样,命令将不再与当前终端关联,因此不会出现在w命令的WHAT列中。 示例: $ command > /dev/null 2>&1 & $ disown 这样,命令就会在后台运行,并且与当前终端会话脱离,w命令将不会显示它。 但是,请注意,这种方法在执行命令的瞬间,w命令可能会短暂显示该命令,因为disown需要手动执行。我们可以将这两条命令写在一行,以减少显示时间: $ command > /dev/null 2>&1 & disown 或者,我们可以使用一个脚本来封装,确保在后台运行并且立即脱离。 另外,还有一种方法是使用setsid命令,它可以让命令在一个新的会话中运行,从而与当前终端无关: $ setsid command > /dev/null 2>&1 这样,命令将不会与当前终端关联,因此也不会出现在w命令的WHAT列中。 综上所述,推荐使用setsid方法,因为它简单且直接。 注意:以上方法都是针对用户希望隐藏命令的情况。但请注意,在安全要求高的环境中,系统管理员可能通过其他手段监控进程,这些方法并不能完全隐藏进程。 因此,回答如下:</think>在Linux中,执行命令时避免在`w`命令的`WHAT`列显示,可通过以下方法实现: ### 方法1:使用`setsid`创建新会话 ```bash setsid command >/dev/null 2>&1 ``` **原理**: `setsid`使命令在**独立会话**中运行,脱离当前终端关联。`w`命令仅显示与终端关联的进程[^1][^4]。 ### 方法2:后台运行 + 重定向输出 ```bash (command >/dev/null 2>&1 &) ``` **原理**: - `&`将命令放入后台 - `>/dev/null 2>&1`屏蔽所有输出 - 括号`()`创建子Shell,命令执行后子Shell立即退出,进程由`init`接管[^1][^4]。 ### 方法3:使用`nohup`脱离终端 ```bash nohup command >/dev/null 2>&1 & ``` **原理**: `nohup`使命令忽略`SIGHUP`信号(终端关闭信号),并自动重定向输出到`nohup.out`(此处屏蔽输出),进程与终端分离[^1]。 --- ### 验证效果 执行后运行`w`命令: ```bash w ``` 输出示例(`WHAT`列无敏感命令): ``` USER TTY FROM LOGIN@ IDLE WHAT user pts/0 192.168.1.5 09:30 5:00 -bash # 仅显示Shell进程 ``` --- ### 注意事项 1. **权限要求**:普通用户可使用上述方法,但需注意命令本身执行权限(参考`chmod`设置[^2])。 2. **监控规避**:系统管理员仍可通过`ps aux`或审计工具追踪进程,此方法仅针对`w`命令有效[^3]。 3. **输出处理**:务必重定向输出(`>/dev/null 2>&1`),否则可能生成日志文件暴露操作痕迹。 > **安全提示**:在企业环境中,频繁隐藏命令可能违反安全策略。建议遵守系统管理规范[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值