简体   繁体   English

从Shell脚本获取完整命令

[英]Get full command from shell script

I'm looking for a way to access the full command from shell script, eg 我正在寻找一种从shell脚本访问完整命令的方法,例如

Assume I have a script called test.sh . 假设我有一个名为test.sh的脚本。 When I run it, the command line is passed to ruby as is (except the script itself is removed). 当我运行它时,命令行按原样传递给ruby(除了脚本本身已删除)。

$ test.sh print ENV['HOME']

Is equivalent to 相当于

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

When you run: 运行时:

test.sh print ENV['HOME']

...then, before test.sh is started, the shell runs string-splitting, expansion, and similar processes. ...然后, 启动test.sh 之前 ,shell将运行字符串拆分,扩展和类似的过程。 Thus, what's eventually run is (assuming no glob expansion): 因此,最终运行的是(假设没有全局扩展):

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

If you have a file named ENVH in the current directory, the shell may treat ENV['HOME'] as a glob, expanding it by replacing the glob expression with the filename, and thus running: 如果当前目录中有一个名为ENVH的文件,那么外壳程序可能会将ENV['HOME']视为glob,通过用文件名替换glob表达式来扩展它,然后运行:

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

...in any event, what exists on the other side of the execv* -series call done to run the new program has no information which was local to the original shell -- and thus no way of knowing what the original command was before parsing and expansion. ...无论如何,执行新程序的execv* -series调用的另一端不存在原始shell本地的信息,因此无法知道之前的原始命令解析和扩展。 Thus, it is impossible to retrieve the original string unless the outer shell is modified to expose it out-of-band (as via an environment variable). 因此,除非修改外壳以使其带外暴露(例如通过环境变量),否则无法检索原始字符串。

This is why your calling convention should instead require: 这就是为什么您的调用约定应该要求:

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

or, allowing even more freedom from shell quoting/escaping syntax, passing program text via stdin, as with: 或者,允许从shell引用/转义语法中获得更大的自由,通过stdin传递程序文本,例如:

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

Now, if you want to modify your shell to do that, I'd suggest a function that exposes BASH_COMMAND . 现在,如果您想修改外壳程序来做到这一点,建议使用一个公开BASH_COMMAND的函数。 For instance: 例如:

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

...then, inside test.sh , you can refer to SHELL_COMMAND . ...然后,在test.sh ,您可以参考SHELL_COMMAND Again, however: This will only work if the calling shell had that trap configured, as within a user's ~/.bashrc ; 但是,再次:仅当调用外壳程序配置了该陷阱(如用户的~/.bashrc内)时,此方法才有效。 you can't simply put the above content in a script and expect it to work, because it's only the interactive shell -- the script's parent process -- that has access to this information and is thus able to expose it. 您不能简单地将上述内容放在脚本中并期望它起作用,因为只有交互式外壳程序(脚本的父进程)才可以访问此信息,从而可以公开这些信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM