如何从 shell 获取准确的命令行字符串?

Posted

技术标签:

【中文标题】如何从 shell 获取准确的命令行字符串?【英文标题】:How to get exact command line string from shell? 【发布时间】:2014-07-17 23:01:39 【问题描述】:

我知道$*$@"$@" 甚至$1+"@" 以及它们的含义。

我需要从 shell 脚本访问 EXACT 命令行参数字符串。请注意示例中的引号。像“$@”这样的东西会保存参数但会删除引号,我不知道如何从中恢复。

例子:

./my-shell.sh "1 2" 3

而且我需要在不进行任何处理的情况下检索 EXACT 参数字符串:

“1 2”3

知道如何实现吗?

【问题讨论】:

您是否能够分别获取命令行参数1 23?如果可以的话,只需将引号添加回第一个参数,然后将两个参数混在一起。 Preserving quotes in bash function parameters 的可能重复项 @RobertHarvey 但是在 "1 2" 3 的情况下如何区分带引号和不带引号的参数?我只需要'原始'字符串。如果我收到1 2 4,我真的需要1 2 4,而不是1 2 4 如果 1 2 被引用了,你难道不把它作为一个单独的参数吗? 这本质上是不可能的,调用 shell 脚本的 shell 会解释命令行字符串并相应地将参数传递给 shell 脚本。换句话说,没有 Unix 程序可以访问调用它的确切命令行,只能访问命令行包含的参数。要看看它在实践中是如何工作的,我推荐strace -fing 你的 shell,因为它会启动一个 shell 脚本;特别注意 execve 调用,它将子进程的控制权转移到脚本。 【参考方案1】:

bash 中,您可以从 shell 历史记录中获取:

set -o history
shopt -s expand_aliases

function myhack 
  line=$(history 1)
  line=$line#*[0-9]  
  echo "You wrote: $line"

alias myhack='myhack #'

如你所描述的那样工作:

$ myhack --args="stuff" * 1..10    $PATH
You wrote: myhack --args="stuff" * 1..10    $PATH

另外,这里有一个方便的图表:

【讨论】:

别名和历史都可以在脚本中启用;它们只是默认关闭。 可爱的图表。但是我需要准确地重现用户输入的命令行,以便能够以编程方式重新执行它以防失败。我认为这属于“其他”。哦,当然,我可以编写自己的算法来根据需要正确再现(嵌套)引号。但如果这个想法没有敲响警钟,我不知道会怎样。 (不幸的是,您的解决方案对我不起作用,因为历史记录已关闭并且在脚本中打开它为时已晚。) @KonradRudolph 如果您想捕获非参数(如重定向和管道)或者您想重新评估代码(以便重新运行 yourscript "$(date +%F).$RANDOM.txt" 将使用新的日期和随机数而不是原始运行)。 @KonradRudolph,为什么需要重现输入,而不是重现输入解析到的数组,或者生成解析到同一个数组的不同可能输入? @CharlesDuffy 因为所述数组不包含重定向,也不包含命令管道的其他部分。【参考方案2】:

但我需要准确地重现用户输入的命令行,以便能够以编程方式重新执行它以防失败

您不需要确切的命令行;您可以自己重建一个等效的(即使不相同!)shell 命令。

#!/usr/bin/env bash
printf -v cmd_q '%q ' "$@"
echo "Executed with a command identical to: $cmd_q"

...虽然你甚至不需要 那个,因为 "$@" 可以按原样重新执行,而不知道启动它的命令是什么:

#!/usr/bin/env bash
printf "Program is starting; received command line equivalent to: "
printf '%q ' "$@"
printf '\n'

if [[ ! $already_restarted ]]; then
  echo "About to restart ourselves:
  exec "$@" # restart the program
fi

【讨论】:

以上是关于如何从 shell 获取准确的命令行字符串?的主要内容,如果未能解决你的问题,请参考以下文章

shell命令行——快捷键

玩转shell命令行

Windows 没有将命令行参数传递给从 shell 执行的 Python 程序

如何写一个命令行解释器(SHELL)

如何写一个命令行解释器(SHELL)

python和shell获取命令行参数的区别