通过shell脚本逃脱美元符号的字符串

时间:2016-06-17 08:34:00

标签: bash shell

假设我有一个名为dd.sh的脚本,我就像这样运行

./dd.sh sample$name.mp4

所以$1是字符串sample$name.mp4

echo '$1' // shows $1

echo "$1" // shows sample.mp4

然后如何处理$1我可以检测参数$1

中是否存在美元符号

我想将字符串处理为sample\$name.mp4,或者仅检测参数$filename

中是否存在美元符号

7 个答案:

答案 0 :(得分:36)

如您所知,美元符号标志着一个变量。您在键入时必须考虑它。

你可以逃脱美元

./dd.sh "sample\$name.mp4"

或只用单引号输入

./dd.sh 'sample$name.mp4'

要检查变量中是否有美元符号,请执行

[[ $variable == *\$* ]] && echo 'I HAZ A DOLAR!!!' || echo 'MEH'

答案 1 :(得分:2)

您的问题不在于echo,而在于$filename。{/ p>

你说

filename="sample$name.mp4"

这将插入字符串,这意味着展开变量$name。这将导致$filename具有值sample.mp4(因为$name可能未定义,这意味着它会扩展为空字符串)

而是在作业中使用单引号:

filename='sample$name.mp4'

echo "$filename"现在会产生预期的sample$name.mp4。显然,由于单引号,echo '$filename'仍会打印$filename

答案 2 :(得分:2)

例如,您有 .env 文件,其中包含用于postgres DB的变量和密码。如您所知,应该使用密码对密码进行加密。所以我们这里有一个问题。因为BASH忽略 $ ,我们总是会得到错误的编码密码。

.env文件


    DB_NAME=sone_db
    DB_PASS=A1$Bb%!Y$  # with dollar signs
    ...

bash脚本


    #!/bin/bash
    PSQL_COMMAND="DROP schema public CASCADE;"
    PSQL_COMMAND+="CREATE schema public;"

    set -o allexport
    # set source file and get access to all variables in .env
    source /path/.env

    ENCODED_PASS=$(python -c "from urllib.parse import quote; print(quote('$DB_PASS'))");
    psql postgres://$DB_USER:$ENCODED_PASS@$DB_HOST:5432/$DB_NAME -c "$PSQL_COMMAND"

    echo $DB_PASS   # returns A1%!Y$
    echo '$DB_PASS' # returns $DB_PASS
    echo "$DB_PASS" # returns A1%!Y$

    # disables variables
    set +o allexport

    # Wont work because BASH find $ sing in string and think that is variable, 
    so in first and last echo missed part $Bb%

要解决此问题,您需要在单引号中的 .env 文件转义字符串中


    ...
    DB_PASS='A1$Bb%!Y$' 
    ...

答案 3 :(得分:1)

如果你的问题是:

  

然后如何处理$ 1,我可以检测是否有一美元   登录参数$ 1

你可以试试这个:

if [[ $1 == *'$'* ]]
then
   echo '$ was found'
else
   echo '$ was not found'
fi

<强>输出:

$ ./dd.sh 'sample$name.mp4'  // prints $ was found
$ ./dd.sh 'samplename.mp4'  // prints $ was not found

答案 4 :(得分:1)

演示:

显然,单引号 ' 导致没有插入封闭字符。

cat > test.sh
echo '$1'
echo "$1"

% ./test.sh hello
$1
hello

% ./test.sh hello$world
$1
hello

% ./test.sh hello\$world
$1
hello$world      << Looks as expected

% ./test.sh 'hello\$world'
$1
hello\$world

% ./test.sh "hello\$world"
$1
hello$world      << Looks as expected

答案 5 :(得分:0)

一个选项:

# Replace occurrences of $ with \$ to prevent variable substitution:
filename="${filename//$/\\$}"

我刚刚意识到我的提示显示foo而不是foo$bar$baz作为当前分支的名称。 foo$bar$baz被分配给PS1,然后$bar$baz被扩展。在PS1中加入分支名称之前,先将美元符号转义,以防止不必要的扩展。

答案 6 :(得分:-1)

我能够通过将这样的$加倍来实现它。

@echo 'export PATH=$$PATH:/usr/local/go/bin' >> $(BASHFILEPATH)

导致

export PATH=$PATH:/usr/local/go/bin

在我的bash文件中