不小心使用了输出重定向 > 而不是管道 |

不小心使用了输出重定向 > 而不是管道 |

一个月前,我编写了一个 Python 脚本来从 stdin 映射 MAC 和 IP 地址。两天前我记得它并用来过滤输出,tcpdump但由于拼写错误而出错了。我输入了

tcpdump -ne > ./mac_ip.py

并且输出什么也没有。但如果它无法解析输入,输出应该是“未知”,所以我做了cat ./mac_ip.py并找到了所有tcpdump数据而不是程序。然后我意识到我应该使用

tcpdump -ne | ./mac_ip.py

有什么办法可以恢复我的程序吗?无论如何,我可以再次编写我的程序,但如果更重要的程序再次发生这种情况,我应该能够做点什么。或者有什么方法可以告诉输出重定向检查文件并警告它是否是可执行文件?

答案1

为了防止现有文件被重定向覆盖,>请使用noclobberinbash或任何类似 POSIX 的 shell 中的选项(也在(t)csh该功能实际起源的地方,尽管您set noclobber在此处而不是set -o noclobber/set -C处)。然后,如果您需要强制替换文件,请使用>|重定向运算符(>!in (t)csh)。

例子:

$ echo abc > file
$ set -o noclobber
$ echo xyz > file
bash: file: cannot overwrite existing file
$ echo xyz >| file
$ cat file
xyz

顺便说一句,您可以使用以下命令检查当前设置set -o

$ set -o
...
monitor         on
noclobber       on
noexec          off
...

答案2

可悲的是我怀疑你需要重写它。 (如果您有备份,那么现在是时候将它们删除。如果没有,我强烈建议您为将来设置一个备份机制。有很多选项可用,但不是本答案的主题。)

我发现将可执行文件放在单独的目录中并将该目录添加到中PATH是有帮助的。这样我就不需要通过显式路径引用可执行文件。我个人(私有)脚本的首选程序目录是"$HOME"/bin,可以将其添加到程序搜索路径中PATH="$HOME/bin:$PATH"。通常这会被添加到 shell 启动脚本.bash_profile和/或.bashrc.

最后,没有什么可以阻止您删除自己对所有可执行程序的写权限:

touch some_executable.py
chmod a+x,a-w some_executable.py    # chmod 555, if you prefer

ls -l some_executable.py
-r-xr-xr-x+ 1 roaima roaima 0 Jun 25 18:33 some_executable.py

echo "The hunting of the Snark" > ./some_executable.py
-bash: ./some_executable.py: Permission denied

答案3

我强烈建议重要脚本在一个git 仓库,远程同步(精美的自托管平台会做的),正如@casey 的评论所说。

这样您就可以避免严重的人为错误,例如将文件恢复到以前的工作状态并再次执行。

答案4

如果您最近查看或编辑了脚本并且该脚本仍在内存缓冲区中,则您可能能够在数据首次发生后恢复数据。否则,你就很不走运了。

如果您通过管道传递 totee写入文件(以及STDOUT)而不是>(或tee -a而不是>>),那么您可以轻松地替换tee为脚本的别名、函数或符号链接,该脚本会警告用户是否要写入文件to 是可执行的。

以下绝不是理想的,可以改进很多,但这只是一个起点,只是作为一个示例来说明这是如何实现的:

wee.sh:

#!/bin/bash

if [ -n "${2}" ]; then
  if [ "$(ls -l "${2}" | awk '{print $1}' | grep x)" ]; then
    echo executable
  else
    tee -a "${2}"
  fi
elif [ "$(ls -l "${1}" | awk '{print $1}' | grep x)" ]; then
  echo executable
else
  tee "${1}"
fi

...然后就是echo 'alias tee="/path/to/wee.sh"' >> ~/.bashrc类似的事情。

从好的方面来说,至少你会得到更多的练习,并且 Python 脚本的第二个版本可能会比第一个版本好得多!

相关内容