Bash标记化带引号的字符串,其中空格作为单个单词 [英] Bash tokenizing quoted string with spaces as individual words

查看:74
本文介绍了Bash标记化带引号的字符串,其中空格作为单个单词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行以下命令:

I'm trying to execute the following commands:

mkdir 'my dir'
CMD="ls 'my dir'"
RESULT=$($CMD)

结果是:

ls: 'my: No such file or directory
ls: dir': No such file or directory

在第二个命令之前使用"set -x"显示实际发出的命令是:

Using "set -x" before the second command reveals that the command that's actually being issued is:

++ ls ''\''my' 'dir'\'''

这显然是从我实际上想做的事情中抽象出来的;此代码本身没有任何作用.但是我的问题是为什么bash会像这样对带引号的字符串进行标记化,如何使它停止?

This is obviously abstracted from what I was actually trying to do; this code on its own doesn't serve any purpose. But my question is why does bash tokenize the quoted string like this and how can I make it stop?

推荐答案

(几乎)所有语言都区分代码和数据:

(Almost) all languages differentiate between code and data:

args="1, 2"
myfunc(args) != myfunc(1, 2)

bash中也是如此.将单引号放在文字字符串中不会使bash解释它们.

The same is true in bash. Putting single quotes in a literal string will not make bash interpret them.

存储程序名称和参数(又名简单命令)的正确方法是使用数组:

The correct way of storing a program name and arguments (aka a simple command) is using an array:

cmd=(ls 'my dir')
result=$("${cmd[@]}")

除非您加双引号,否则Bash会自动在空格上分割单词,这就是为什么您的示例有时会起作用的原因.这是令人惊讶且容易出错的原因,也是除非您有充分的理由不这么做的原因,否则应始终对变量加双引号的原因.

Bash will automatically split words on spaces unless you double quote, which is why your example sometimes appears to work. This is surprising and error prone, and the reason why you should always double quote your variables unless you have a good reason not to.

还可以使用eval使bash将字符串解释为完全是bash代码.经常建议这样做,但几乎总是错误的.

It's also possible to get bash to interpret a string as if it was bash code entirely, using eval. This is frequently recommended, but almost always wrong.

这篇关于Bash标记化带引号的字符串,其中空格作为单个单词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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