linux - 从 shell 脚本获取完整命令

标签 linux bash shell unix scripting

我正在寻找一种从 shell 脚本访问完整命令的方法,例如

假设我有一个名为 test.sh 的脚本。当我运行它时,命令行按原样传递给 ruby​​(除了脚本本身被删除)。

$ test.sh print ENV['HOME']

相当于

$ ruby -e "print ENV['HOME']"

最佳答案

当你运行时:

test.sh print ENV['HOME']

...然后, test.sh 启动之前,shell 运行字符串拆分、扩展和类似过程。因此,最终运行的是(假设没有全局扩展):

execvp("test.sh", {"test.sh", "print", "ENV[HOME]"});

如果在当前目录中有一个名为 ENVH 的文件,shell 可能会将 ENV['HOME'] 视为一个 glob,通过替换 glob 表达式来扩展它使用文件名,然后运行:

execvp("test.sh", {"test.sh", "print", "ENVH"});

...在任何情况下,execv* 系列调用另一端存在的运行新程序的信息都没有原始 shell 的本地信息——因此在解析和扩展之前无法知道原始命令是什么。 因此,除非修改 shell 以带外公开(如通过环境变量),否则无法检索原始字符串。

这就是为什么您的调用约定应该改为要求:

test.sh "print ENV['HOME']"

或者,允许从 shell 引用/转义语法中获得更多自由,通过标准输入传递程序文本,如:

test.sh <<'EOF'
print ENV['HOME']
EOF

现在,如果你想修改你的 shell 来做到这一点,我建议使用一个公开 BASH_COMMAND 的函数。例如:

shopt -s extdebug
expose_command() {
  export SHELL_COMMAND="$BASH_COMMAND"
  return 0
}
trap expose_command DEBUG

...然后,在test.sh 中,您可以引用SHELL_COMMAND。然而,再次重申:这仅在调用 shell 配置了该陷阱时才有效,如在用户的 ~/.bashrc 中;您不能简单地将上述内容放在脚本中并期望它起作用,因为只有交互式 shell(脚本的父进程)可以访问此信息并因此能够公开它。

关于linux - 从 shell 脚本获取完整命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27831439/

相关文章:

python - 如何计算多个csv文件中数字的平均值?

linux - 如何获取influxdb中当前值和之前值的差值?

linux - 如何 Hook 特定共享 ELF 库的函数?

linux - 带有 grep 的 Bash 函数,使用 if 和 then 语句

python - 处理 unix 中文件名中的无效字符

c++ - 如何实现shell的作业控制

c++ - 在 linux ubuntu 上运行 Qt 5 中的 qwt 示例

javascript - 强制窗口对开发区分大小写

arrays - Bash - 仅在出现新行而不是空格时进入下一个索引?

windows - 在 Windows 上,Git Bash vs Windows Powershell vs 命令提示符有什么区别