以各种方式被引用时,如何正确地转义bash变量 [英] How can I properly escape bash variables when being quoted in various ways

查看:114
本文介绍了以各种方式被引用时,如何正确地转义bash变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

set -o xtrace
openDirectory ()
{
    lxterminal --command="zsh -c 'cd "$1"; zsh -i' "
}

# Handle argument.
if [ "$@" ]
then
  openDirectory ~/Projects/Clients/"@1"
  cd $1
fi

如果传递的参数中有空格,此操作将失败。

This fails if there is a space in the argument passed.

lxterminal '--command=zsh -c '\''cd /home/chris/Projects/Clients/Test' - 'Space; zsh -i'\'' '
cd Test - Space
cd: too many arguments

如何正确地避免这种情况?

How can I properly escape this? Is this even feasible to be done with something like bash?

推荐答案

假设封闭的外壳确实是bash(因为这个问题已被标记),这甚至可行吗? ),则可以使用 printf -v varname%q $ var 存储值 var 放入名为 varname 的变量中,例如:

Assuming the enclosing shell really is bash (as the question is tagged), you can use printf -v varname %q "$var" to store a safely quoted instance of the value of var into the variable named varname, as such:

openDirectory()
{
    local cd_cmd cmd
    printf -v cd_cmd '%q ' cd "$1"
    printf -v cmd '%q ' zsh -c "$cd_cmd && zsh -i"
    lxterminal --command="$cmd"
}

printf'%q'计算为给定字符串的版本,当bash eval 'ed时,该版本(或具有等效语义的任何外壳程序),求值为原始文字值。

printf '%q' evaluates to a version of the given string which will, when eval'ed by bash (or any shell with equivalent semantics), evaluate to the original literal value.

要解释为什么这样做是这样的:

To explain why this is done that way:


  • 在上面,代码本身包含的所有引号字符都是句法而不是文字:取决于 all 引用和转义的 printf%q 。这是一种最佳实践方法:使用文字引号意味着生成的数据中的文字可以转义这些引号。

  • 运行shell指令,例如& & 通过外壳引号会将它们转换为文字数据。因此,当我们将&& 作为参数传递给<$ c $时,我们希望是文字数据,而不是语法c> -c ,但不是由远程Shell处理时的文字数据,这就是为什么它仅出现在 last 引用传递中的原因。

  • In the above, all quote characters included in the code itself are syntactic rather than literal: We're depending on printf %q for all quoting and escaping. This is a best-practice approach: Using literal quotes means that literals inside the data being generated are able to escape those quotes.
  • Running shell directives such as && through shell quoting will make them into literal data. Thus, we want the && to be literal data rather than syntax when we're passing it as an argument to -c, but not literal data when handled by the remote shell -- this is why it's only present in the last quoting pass.

这篇关于以各种方式被引用时,如何正确地转义bash变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆