在一个bash脚本单引号问题 [英] Problems with single quotes in a bash script

查看:113
本文介绍了在一个bash脚本单引号问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图运行bash脚本的命令。该命令本身中有单引号,但我不能让他们的工作,因为有需要扩大单引号内的变量。下面是bash脚本:

I am trying to run a command from a bash script. The command itself has single quotes in it, but I can't get them to work as there are variables inside the single quotes that need to be expanded. Here is the bash script:

#!/bin/bash

if [ "$2" == "PracSci" ];
then
    echo "Running tabulate.science.r"
    R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.science.r /dev/tty
else
    echo "Running tabulate.r"
    R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/tty
fi

在身份运行 ./ script.sh 2翻译May12 例如,命令本身不带变量的值运行。

When run as ./script.sh 2 Vocab May12 for example, the command itself is run without the variables values.

如何展开变量同时还获得运行命令?

How can I expand the variables while still getting the command to run?

只是要清楚,我想要运行的命令是:
研究CMD批--no保存--no-恢复--slave--args $ 1 $ 2 $ 3'tabulate.r为/ dev / tty的(包括单引号命令)。

Just to be clear, the command I am trying to run is: R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/tty (including the single quotes in the command).

感谢您!

推荐答案

简短的回答:使用双引号来代替单引号(如@Pavel建议)。而当有疑问,请使用设置-x 来找出外壳是如何分析你的命令。

Short answer: use double-quotes instead of single-quotes (as @Pavel suggested). And when in doubt, use set -x to find out how the shell is parsing your commands.

龙回答:报价不会传递到命令;相反,它们被shell解析(和删除),参数传递给命令之前。他们做的是改变壳解析什么是引号内(一般由SUP pressing的一些字符的特殊含义),这意味着你需要选择合适的报价,让你想要解析的特殊字符的方式,和SUP preSS你想被视为只是普通的字符的人。例如,考虑下面的命令:

Long answer: quotes aren't passed to the command; instead, they are parsed (and removed) by the shell, before the arguments are passed to the command. What they do is to change the way the shell parses what's inside the quotes (generally by suppressing the special meanings of some characters), which means that you need to choose the appropriate quotes to allow the special characters you want parsed, and suppress the ones you want treated as just plain characters. For instance, consider the following command:

R CMD BATCH --no-save --no-restore --slave '--args 2 Vocab May12' tabulate.r /dev/tty

外壳将忽略命令的单引号部分的所有字符的特殊含义。唯一的字符的任何特殊含义有空间,一般作为参数之间的分隔符;在这种情况下,单引号使外壳把它们作为一个参数的一部分。这些其他的命令:

The shell will ignore the special meanings of all characters in the single-quoted section of the command. The only characters with any special meaning there are the spaces, which normally act as separators between arguments; in this case, the single-quotes make the shell treat them as part of a single argument. These other commands:

R CMD BATCH --no-save --no-restore --slave "--args 2 Vocab May12" tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args' '2' 'Vocab' 'May12 tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args\ 2\ Vocab\ May12 tabulate.r /dev/tty

...都做同样的事情,因为他们都(这种或那种方式)获取shell将空格作为参数的一部分,而不是参数之间的分隔符。

...all do exactly the same thing, because they all (one way or another) get the shell to treat the spaces as part of an argument, rather than separators between arguments.

现在,让我们来看看这是不是为你工作的命令:

Now, let's look at the command that isn't working for you:

R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/tty

问题是,尽管单引号是燮pressing空间的特殊意义(如你想要的),他们也很燮pressing的特殊含义 $ S(你不想要的)。所以,你需要的东西更有选择性。一个办法是引用/逃脱的空间,但离开 $ 1 等不带引号的:

The problem is that while the single-quotes are suppressing the special meaning of the spaces (as you want), they're also suppressing the special meaning of the $s (which you don't want). So you need something more selective. One option would be to quote/escape the spaces but leave the $1 etc unquoted:

R CMD BATCH --no-save --no-restore --slave --args' '$1' '$2' '$3 tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args\ $1\ $2\ $3 tabulate.r /dev/tty

(注意,这两个命令做同样的事情。)这些将主要工作,但有一点麻烦的潜在的:shell将取代 $ 1 等与脚本变量的,但后来它确实对他们一些额外的分析:寻找将参数分割使用,通配符做文件名匹配上,等所有的事情我是pretty确保您不会想要的 - 尽管从参数可能不会包含任何特殊字符这可能不会是一个问题。也许吧。

(note that both of these commands do exactly the same thing.) These would mostly work, but have a bit of a potential for trouble: the shell will replace $1 etc with the arguments to the script, but then it does some additional parsing on them: looking for spaces to use as argument separators, wildcards to do filename matching on, etc. All things I'm pretty sure you don't want -- although since the arguments probably won't contain any special characters this probably won't be an issue. Probably.

我看到的最好的选择是简单地使用双引号:

The best option I see is to simply use double-quotes:

R CMD BATCH --no-save --no-restore --slave "--args $1 $2 $3" tabulate.r /dev/tty

双引号燮preSS空格的特殊意义(如你想要的),让 $ 来触发变量扩展(也可作为你想要的),但prevent任何进一步的解析,一旦变量已扩展(也你想大概是什么)。空格或其他有趣的字符参数仍然可能导致第r脚本中的麻烦,但至少这$ P $从作祟第r脚本甚至开始之前pvents他们。

Double-quotes suppress the special meaning of spaces(as you want), allow $ to trigger variable expansion (also as you want), BUT prevent any further parsing once the variables have been expanded (also probably what you want). Spaces or other funny characters in arguments might still cause trouble within the R script, but at least this prevents them from causing trouble before the R script is even started.

这篇关于在一个bash脚本单引号问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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