假设我们在 bash 脚本中有 2 个整数:
value1=5
value2=3
Run Code Online (Sandbox Code Playgroud)
那么为什么我们需要在测试的情况下使用双引号呢?例如:
if [[ "$value1" -eq "$value2" ]]
Run Code Online (Sandbox Code Playgroud)
为什么不使用以下内容?
if [[ $value1 -eq $value2 ]]
Run Code Online (Sandbox Code Playgroud)
对我来说,双引号没有任何意义。
为简单起见,我想做:
echo cart | assign spo;
echo $spo
Run Code Online (Sandbox Code Playgroud)
输出:购物车
是否assign存在这样的应用程序?
我知道使用替换来做到这一点的所有方法。
如何在命令行中将 shell 变量连接到其他参数?
例如,
#!/bin/sh
WEBSITE="danydiop"
/usr/bin/mysqldump --opt -u root --ppassword $WEBSITE > $WEBSITE.sql
Run Code Online (Sandbox Code Playgroud)
我需要连接.sql到$WEBSITE
我有一个"rtcpOnNbActive true"存储在变量中的字符串x。我想提取“true”作为子字符串并存储在一个变量中。我怎样才能做到这一点?
我想用来printf打印一个变量。此变量可能包含%百分号。
最小的例子:
$ TEST="contains % percent"
$ echo "${TEST}"
contains % percent
$ printf "${TEST}\n"
bash: printf: `p': invalid format character
contains $
Run Code Online (Sandbox Code Playgroud)
(echo提供所需的输出。)
shell 脚本中的一般规则是,除非有令人信服的理由,否则应该始终引用变量。有关您可能想知道的更多详细信息,请查看这个很棒的问答:忘记在 bash/POSIX shell 中引用变量的安全隐患。
但是,请考虑如下函数:
run_this(){
$@
}
Run Code Online (Sandbox Code Playgroud)
应该$@在那里引用还是不引用?我玩了一会儿,找不到任何缺少引号引起问题的情况。另一方面,在传递包含空格的命令作为引用变量时,使用引号会使它中断:
#!/usr/bin/sh
set -x
run_this(){
$@
}
run_that(){
"$@"
}
comm="ls -l"
run_this "$comm"
run_that "$comm"
Run Code Online (Sandbox Code Playgroud)
运行上面的脚本返回:
$ a.sh
+ comm='ls -l'
+ run_this 'ls -l'
+ ls -l
total 8
-rw-r--r-- 1 terdon users 0 Dec 22 12:58 da
-rw-r--r-- 1 terdon users 45 Dec 22 13:33 file
-rw-r--r-- 1 terdon users 43 Dec 22 12:38 file~
+ run_that 'ls -l'
+ 'ls -l'
/home/terdon/scripts/a.sh: line …Run Code Online (Sandbox Code Playgroud) 我读到我应该在 bash 中引用变量,例如“$foo”而不是 $foo。但是,在编写脚本时,我发现了一个案例,它没有引号但不能使用引号:
wget_options='--mirror --no-host-directories'
local_root="$1" # ./testdir recieved from command line
remote_root="$2" # ftp://XXX recieved from command line
relative_path="$3" # /XXX received from command line
Run Code Online (Sandbox Code Playgroud)
这个有效:
wget $wget_options --directory_prefix="$local_root" "$remote_root$relative_path"
Run Code Online (Sandbox Code Playgroud)
这个没有(注意 $wget_options 周围的双引号):
wget "$wget_options" --directory_prefix="$local_root" "$remote_root$relative_path"
Run Code Online (Sandbox Code Playgroud)
这是什么原因?
第一行是不是好版本;还是我应该怀疑某处存在导致这种行为的隐藏错误?
一般来说,我在哪里可以找到好的文档来了解 bash 及其引用的工作原理?在编写这个脚本的过程中,我觉得我开始在试错的基础上工作,而不是理解规则。
在尝试在 中设置最后一个位置参数时/bin/dash,我尝试了echo ${$#}. 令人惊讶的是,这并没有导致错误,而是进入了与$$变量内容相同的 PID 。问题是,为什么这种语法有效?shell 在这里应用的语法规则是什么?
基本上,我所做的是
$ set 1 2 3 4 5
$ echo ${$#}
13819
$ echo $$
13819
Run Code Online (Sandbox Code Playgroud)
显然,%在这样的构造中,字符也会被忽略
$ echo ${$%}
13819
Run Code Online (Sandbox Code Playgroud)
但是*并@导致错误的替换错误:
$ echo ${$*}
sh: 10: Bad substitution
$ echo ${$@}
sh: 11: Bad substitution
Run Code Online (Sandbox Code Playgroud) 在FreeBSD 12 中,使用zshshell,我在查看$path(小写)和$PATH(大写)时注意到了这种差异。
echo $path
Run Code Online (Sandbox Code Playgroud)
/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin /usr/home/freebsd/bin
echo $PATH
Run Code Online (Sandbox Code Playgroud)
/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/home/freebsd/bin
一个输出由 SPACE 字符分隔,另一个由 COLON 字符分隔。
? 为什么会有差异?
这是两个不同的独立变量吗?还是小写/大写会触发某种我不知道的技巧或含义?
这是一个zsh功能吗?还是 FreeBSD 的一个特性?