【问题标题】:Bash: Execute command WITH ARGUMENTS in new terminalBash:在新终端中执行带参数的命令
【发布时间】:2017-08-31 13:04:14
【问题描述】:

所以我想在 bash 中打开一个新终端并执行带有参数的命令。 只要我只将 ls 之类的命令用作命令,它就可以正常工作,但是当我采用 route -n 之类的命令时,带有参数的命令就不起作用。 代码:

gnome-terminal --window-with-profile=Bash -e whoami#WORKS

gnome-terminal --window-with-profile=Bash -e route -n#DOESNT 工作

我已经尝试在命令周围加上“”,但它仍然不起作用

【问题讨论】:

标签: bash terminal command arguments quoting


【解决方案1】:

您可以使用以下命令启动新终端:

gnome-terminal --window-with-profile=Bash -- \
    bash -c "<command>"

要使用正常的 bash 配置文件继续终端,请添加 exec bash:

gnome-terminal --window-with-profile=Bash -- \
    bash -c "<command>; exec bash"

以下是创建Here document 并将其作为命令传递的方法:

cmd="$(printf '%s\n' 'wc -w <<-EOF
  First line of Here document.
  Second line.
  The output of this command will be '15'.
EOF' 'exec bash')"

xterm -e bash -c "${cmd}"

要打开一个新终端并使用脚本运行初始命令,请在脚本中添加以下内容:

nohup xterm -e bash -c "$(printf '%s\nexec bash' "$*")" &>/dev/null &

$* 被引用时,它将参数扩展为一个单词,每个单词由 IFS 的第一个字符分隔。 nohup&amp;&gt;/dev/null &amp; 仅用于允许终端在后台运行。

【讨论】:

  • echo "${cmd}" 不是很便携。请记住,$(...) 扩展是使用当前 shell 运行的,not 使用 bash,所以你不知道它是谁的 echo 实现。请参阅 [echo 的 POSIX 规范](pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html) 以了解其行为的不确定/不可靠程度。
  • echo "${@}" 特别不可靠。出于显而易见的原因,您无法区分 echo "hello" "world"echo "hello world"
  • 如果保证你的外壳是 bash 或 ksh,最好使用printf '%q ' "$@" 来形成一个正确引用的命令(printf -v cmd '%q ' "$@",如果它已知的话是 bash;ksh 优化了 cmd=$(printf '%q ' "$@") 以避免分叉一个实际的子 shell,但 bash 没有)。
  • 谢谢@CharlesDuffy。这实际上只在 bash 中进行了测试。我将使用不同的外壳测试您的解决方案并相应地更新答案。
  • 我建议使用类似printf '%s\n' "hello world" "*" "goodbye world" 的命令作为被测命令,以便检测到引用/字符串拆分问题。
【解决方案2】:

试试这个:

gnome-terminal --window-with-profile=Bash -e 'bash -c "route -n; read"'

最后的read 防止窗口在执行前面的命令后关闭。当你按下一个键时它会关闭。

如果你想体验头痛,你可以尝试更多的引用嵌套:

gnome-terminal --window-with-profile=Bash \
  -e 'bash -c "route -n; read -p '"'Press a key...'"'"'

(在以下示例中,没有最终的read。假设我们在配置文件中修复了它。)

如果您想打印空行并享受多级转义:

gnome-terminal --window-with-profile=Bash \
  -e 'bash -c "printf \\\\n; route -n"'

相同,但引用风格不同:

gnome-terminal --window-with-profile=Bash \
  -e 'bash -c '\''printf "\n"; route -n'\'

变量用双引号展开,而不是单引号,所以如果你想让它们展开,你需要确保最外面的引号是双引号:

command='printf "\n"; route -n'
gnome-terminal --window-with-profile=Bash \
  -e "bash -c '$command'"

报价会变得非常复杂。当您需要比几个简单的命令更高级的东西时,建议您编写一个独立的 shell 脚本,其中包含您需要的所有可读、参数化的代码,将其保存在某处,例如 /home/user/bin/mycommand,然后简单地调用它

gnome-terminal --window-with-profile=Bash -e /home/user/bin/mycommand

【讨论】:

  • 真棒兄弟,这工作 :D 顺便说一句,我在配置文件中定义它不会关闭,所以我不需要阅读,但很高兴看到它也可以这样工作。只有一个问题:我如何将printf "\n" 集成到代码中,所以基本上我希望它在执行另一个命令之前打印一个空行,我尝试在route -n 前面写它,但它什么也没做。
  • 根据您的要求使用printf \\\\n 编辑...引用和转义往往会失控...
  • 我怎样才能向它添加变量,比如command="route -n" ... 'bash -c "$command"'(
  • 再次编辑。 :)
  • 非常感谢兄弟!!!您无法相信您对我的帮助有多大 :D 而且我总是使用双引号,所以这对我来说是完美的 :D 并且感谢您再次在这里编写文件版本,尽管我已经知道了,但是我的命令太简单了。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 2016-10-09
相关资源
最近更新 更多