0

我有一些将当前时间戳写入某个文件的 bash 脚本:

#!/usr/bin/env bash
nohup & sh -c 'while [[ 1 ]];
do
    vardate=$(date +%d\-%m\-%Y\_%H.%M.%S);
    echo $vardate >> ~/test.txt;
    sleep 1;
done' &

当我ps -ef在所有进程的列表中运行时,我可以看到它:

...
501 32034     1   0 10:17PM ttys000    0:00.97 sh -c while [[ 1 ]];\012do\012    vardate=$(date +%d\-%m\-%Y\_%H.%M.%S);\012    echo $vardate >> ~/test.txt;\012    sleep 1;\012done
...

是否有可能完全隐藏此 PID 或至少隐藏脚本的内容?

4

1 回答 1

1

ps本身不显示脚本的内容。相反,它显示的是正在运行的命令的命令行。恰好该命令是由您的脚本启动的,因此出现在其中。

事实上,脚本本身就很奇怪。它已经是一个 shell 脚本,那么显式启动一个新的、单独的 shell 来运行while循环 ( sh -c) 的目的是什么?我认为让脚本直接执行循环没有任何优势。

例子:

#!/usr/bin/env bash
while [[ 1 ]];
do
    vardate=$(date +%d\-%m\-%Y\_%H.%M.%S);
    echo $vardate >> ~/test.txt;
    sleep 1;
done

或者,如果确实有意不在当前 shell 中执行循环,那么为什么不使用()操作符在子 shell 中运行它呢?

示例

#!/usr/bin/env bash
(
  while [[ 1 ]];
  do
    vardate=$(date +%d\-%m\-%Y\_%H.%M.%S);
    echo $vardate >> ~/test.txt;
    sleep 1;
  done
)

两者都可能会避免该while命令出现在您的ps列表中。

针对问题更新:

问题仍然存在,如果您使用sh -c(或bash -c) 执行脚本文本,那么该脚本文本是命令行的一部分,并且可以通过ps. 解决方案也是相同的:通过输入而不是命令行选项将脚本提供给 shell。您可以nohup使用heredoc将其与后台执行结合起来:

#!/usr/bin/env bash

nohup "$BASH" >> ~/test.txt 2>&1 <<'EOF' &
while [[ 1 ]]; do
  date +%d\-%m\-%Y\_%H.%M.%S
  sleep 1
done
EOF

这包括比您的原始内容更多的更改,而不是严格必要的。下面是一个总结,大致按照出现的顺序:

  • 您不需要或不希望&立即执行该nohup命令。我已经省略了。
  • 此版本执行 bash,而不是sh,它通过自动变量执行此操作$BASH,该变量扩展为启动当前 bash 实例的文件名。
  • nohup 命令(启动bash)的全部输出以及它的标准错误被重定向到输出文件(>> ~/test.txt 2>&1)。这会抑制以其他方式为我显示的诊断,并且它比每秒打开和关闭输出文件一次更有效,就像原始文件一样。
  • 该命令的输入(实际上是nohup's)是从 heredoc 重定向的,而不会被当前 shell ( <<'EOF'... EOF) 扩展。这是防止脚本内容出现在进程列表中的关键组件。值得注意的是,heredoc 内容实际上直到下一行才开始,因此它不包括&. 这很重要,因为它会&终止命令(实际上是它所属的整个管道),所以它不能更早出现。
  • 消除了vardate变量和echo命令,只允许date直接打印输出。
于 2019-08-02T20:42:49.477 回答