命令替换有两种语法:美元括号和反引号。运行top -p $(pidof init)并top -p `pidof init`给出相同的输出。这两种做同样事情的方式,还是有区别?
root@server # tar fcz bkup.tar.gz /home/foo/
tar: Removing leading `/' from member names
Run Code Online (Sandbox Code Playgroud)
如何解决此问题并保留/文件名?
我对使用单括号或双括号感到困惑。看看这段代码:
dir="/home/mazimi/VirtualBox VMs"
if [[ -d ${dir} ]]; then
echo "yep"
fi
Run Code Online (Sandbox Code Playgroud)
尽管字符串包含空格,但它工作得很好。但是当我将其更改为单括号时:
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then
echo "yep"
fi
Run Code Online (Sandbox Code Playgroud)
它说:
./script.sh: line 5: [: /home/mazimi/VirtualBox: binary operator expected
Run Code Online (Sandbox Code Playgroud)
当我将其更改为:
dir="/home/mazimi/VirtualBox VMs"
if [ -d "${dir}" ]; then
echo "yep"
fi
Run Code Online (Sandbox Code Playgroud)
它工作正常。有人可以解释发生了什么吗?什么时候应该在变量周围分配双引号,"${var}"以防止空格引起的问题?
我在脚本中看到过这样的结构:
if somevar="$(somecommand 2>/dev/null)"; then
...
fi
Run Code Online (Sandbox Code Playgroud)
这是在某处记录的吗?变量的返回状态是如何确定的,它与命令替换有什么关系?(例如,我会得到相同的结果if echo "$(somecommand 2>/dev/null)"; then吗?)
可能的重复:
获取通过管道传输到另一个进程的退出代码
我正在使用以下命令行(在 makefile 中)通过 perl 脚本将来自编译器的详细错误消息通过管道传输,该脚本将它们简化为人类可读的内容:
g++ -c source.cpp -o source.o 2>&1 | perl /bin/gSTLFilt.pl
Run Code Online (Sandbox Code Playgroud)
不幸的是,这种方法“屏蔽”了g++命令返回的错误值。make 不知道该g++命令已失败,因为它返回的只是perl命令的错误结果。
有没有办法通过管道输出,并仍然保留原始错误条件?
如果它有所不同:我在运行 GNU bash 版本 2.04.0(1)-release (i686-pc- msys) 在 Windows XP 上。
请参阅以下示例及其在 POSIX shell 中的输出:
false;echo $?或false || echo 1:1false;foo="bar";echo $?或foo="bar" && echo 0:0foo=$(false);echo $?或foo=$(false) || echo 1:1foo=$(true);echo $?或foo=$(true) && echo 0:0正如/sf/ask/478414121/ 上投票最高的答案所提到的:
$?用于查找上次执行命令的返回值。
在这种情况下,这可能有点误导,所以让我们获取 POSIX 定义,该定义也在该线程的帖子中引用:
? 扩展到最近管道的十进制退出状态(请参阅管道)。
所以看起来好像一个赋值本身算作一个命令(或者更确切地说是一个管道部分),它的退出值为零,但它应用在赋值的右侧之前(例如,我的示例中的命令替换调用)。
从实际的角度来看,我看到这种行为是有道理的,但对我来说,作业本身按该顺序计数似乎有些不寻常。也许为了让我更清楚为什么这对我来说很奇怪,让我们假设赋值是一个函数:
ASSIGNMENT( VARIABLE, VALUE )
Run Code Online (Sandbox Code Playgroud)
那么foo="bar"将是
ASSIGNMENT( "foo", "bar" )
Run Code Online (Sandbox Code Playgroud)
并且foo=$(false)会像
ASSIGNMENT( "foo", EXECUTE( "false" ) )
Run Code Online (Sandbox Code Playgroud)
这意味着首先EXECUTE …
我试图了解使用管道时如何传达退出状态。假设我which用来定位一个不存在的程序:
which lss
echo $?
1
Run Code Online (Sandbox Code Playgroud)
由于which无法定位,lss我的退出状态为 1。这很好。但是,当我尝试以下操作时:
which lss | echo $?
0
Run Code Online (Sandbox Code Playgroud)
这表明最后执行的命令已经正常退出。我能理解的唯一方法是 PIPE 可能也会产生退出状态。这是正确的理解方式吗?
在学习(或多或少)一些关于管道的有用讨论后,例如 获取通过管道传输到另一个进程的进程的退出状态和当管道中的一个进程失败时退出,我仍然无法避免在第一个命令失败时启动第二个命令。我是否缺少有关管道的基本细节?
所以例如
$ somecommand | tar -T - -czf /tmp/someProject.tar.gz
Run Code Online (Sandbox Code Playgroud)
tar.gz如果somecommand不能正常工作并且只产生一些错误消息而不是预期的文件列表,则不应创建几乎为空的文件。
考虑源代码:
1. 父.sh
#!/usr/bin/ksh
# No tee
ksh Child.sh;
exit_status=$?;
echo "Exit status: ${exit_status}"
# Using tee
ksh Child.sh | tee -a log.txt;
exit_status=$?;
echo "Exit status: ${exit_status}"
Run Code Online (Sandbox Code Playgroud)
2. 子.sh
#!/usr/bin/ksh
...
exit 1;
Run Code Online (Sandbox Code Playgroud)
输出:
Exit status: 1
Exit status: 0
Run Code Online (Sandbox Code Playgroud)
$exit_status正在捕获 Child.sh 的退出状态,1.$exit_status正在捕获 tee 的退出状态,即0.那么如何捕获退出状态并使用 tee 呢?
我有solaris机器(solaris 10)
请查看以下简单命令(haconf -makerw | grep -iq "Cluster already writable")
# haconf -makerw
VCS WARNING V-16-1-10364 Cluster already writable.
haconf -makerw | grep -iq "Cluster already writable"
# echo $?
0
Run Code Online (Sandbox Code Playgroud)
我从 grep 得到退出状态 0,
这是正确的(因为我们总是在最后一个命令中获得 exe 状态)
但
我的问题是:
如何从命令haconf -makerw 代替 grep获取退出状态( $? )?
或者需要在我的语法中添加什么才能了解 haconf -makerw 是否成功?
haconf -makerw | grep -iq "Cluster already writable"
# echo $? ( will print the exe status from haconf -makerw )
Run Code Online (Sandbox Code Playgroud) bash ×5
pipe ×3
shell-script ×3
command-line ×2
exit-status ×2
ksh ×2
shell ×2
assignment ×1
command ×1
exit ×1
gzip ×1
linux ×1
posix ×1
quoting ×1
solaris ×1
tar ×1
test ×1
variable ×1
zsh ×1