![针对新手的一些 Bash 问题](https://linux22.com/image/1116948/%E9%92%88%E5%AF%B9%E6%96%B0%E6%89%8B%E7%9A%84%E4%B8%80%E4%BA%9B%20Bash%20%E9%97%AE%E9%A2%98.png)
我正在学习 Bash,但有些东西我的书上没有解释。首先我会发布一个脚本,然后我会通过脚本提问。
Bash 脚本:
$ cat sortmerg
#!/bin/bash
usage ()
{
if [ $# -ne 2 ]; then
echo "Usage: $0 file1 file2" 2>&1
exit 1
fi
}
# Default temporary directory
: ${TEMPDIR:=/tmp}
# Check argument count
usage "$@"
# Set up temporary files for sorting
file1=$TEMPDIR/$$.file1
file2=$TEMPDIR/$$.file2
# Sort
sort $1 > $file1
sort $2 > $file2
# Open $file1 and $file2 for reading. Use file descriptors 3 and 4.
exec 3<$file1
exec 4<$file2
# Read the first line from each file to figure out how to start.
read Line1 <&3
status1=$?
read Line2 <&4
status2=$?
# Strategy: while there is still input left in both files:
# Output the line that should come first.
# Read a new line from the file that line came from.
while [ $status1 -eq 0 -a $status2 -eq 0 ]
do
if [[ "$Line2" > "$Line1" ]]; then
echo -e "1.\t$Line1"
read -u3 Line1
status1=$?
else
echo -e "2.\t$Line2"
read -u4 Line2
status2=$?
fi
done
# Now one of the files is at end-of-file.
# Read from each file until the end.
# First file1:
while [ $status1 -eq 0 ]
do
echo -e "1.\t$Line1"
read Line1 <&3
status1=$?
done
# Next file2:
while [[ $status2 -eq 0 ]]
do
echo -e "2.\t$Line2"
read Line2 <&4
status2=$?
done
# Close and remove both input files
exec 3<&- 4<&-
rm -f $file1 $file2
exit 0
问题:
首先,如何在 Gedit 中缩进代码?我从一本书中复制并粘贴了代码,但它不会自动缩进代码。您通常使用 Gedit 或任何其他流行的编辑器来编写 bash 脚本吗?
: ${TEMPDIR:=/tmp}
你能解释一下这是什么吗?我有 C# 和其他编程语言的编程知识。那么你能告诉我,假设我不是编程新手,这个:键和花括号键有什么用吗?if [[ "$Line2" > "$Line1" ]]; then
[]
与测试相同。但是为什么会[[]]
有所不同?status1=$?
什么是$?
?
提前谢谢了。
答案1
我使用 vim 编写 shell 脚本。
${TEMPDIR}
将扩展为名为 TEMPDIR 的变量的值。${TEMPDIR:=/tmp}
将执行相同操作,但如果它为空(或未设置),则值 /tmp 将被分配给 TEMPDIR,并且也会扩展。单独
${TEMPDIR:=/tmp}
在一行上,将导致它被更改为例如,它将尝试作为命令/tmp
执行(这显然会失败,因为您无法执行目录)。这就是使用 (null) 命令的原因。null 命令忽略所有输入、所有参数,并且绝对不执行任何操作。运行以查看该内置命令的描述。/tmp
:
help :
看http://mywiki.wooledge.org/BashFAQ/073使用参数扩展可以做各种事情。
[[ "$line2" > "$Line1" ]]
如果 line2 排在 line1 之后 (类似 C 语言中的 strcmp),则返回 true。[(“test” 命令) 和 [[ (“new test” 命令) 用于评估表达式。[[ 仅适用于 Bash、Zsh 和 Korn shell,并且功能更强大;[ 和 test 在 POSIX shell 中可用。
看http://mywiki.wooledge.org/BashFAQ/031
[
命令和关键字之间的区别[[
。?
是特殊参数它保存了最后执行的命令的退出状态。$?
扩展该参数的值。
顺便说一句,如果这是你书中的一个例子,我会说这是一个学习 bash 的糟糕资源。我建议阅读http://mywiki.wooledge.org/BashGuide这也教会了我们良好的做法。
答案2
是的,您在 Gedit 中有缩进。打开 gedit 并在“编辑”->“首选项”中,您可以使用自动缩进选项。
关于第二点,它的意思就像假设 TEMPDIR 位于/tmp
位置。
答案3
要在 Gedit 中缩进代码,请按Tab键,然后按Shift-Tab取消缩进。您需要的所有信息和热键列表位于gedit 的 Gnome 文档部分
该
:
命令是内置的 Bash 命令,除了返回 0(真)外不执行任何操作;但在这种情况下,它用于允许对参数扩展进行评估${VAR:=VALUE}
,只有当它不存在时才将其分配给。如果VALUE
(在您的情况下)已经有一个值,则不会对其进行修改。它相当于构造:$VAR
$VAR
$TEMPDIR
[[ -z "$TEMPDIR" ]] && TEMPDIR=/tmp
即,“如果
$TEMPDIR
为空,则评估右侧的命令(分配/tmp
给TEMPDIR
)”。该
[[
命令是内置的 Bash 命令(和 一样[
;test
它们也有可执行等效命令)。与或相比,该命令[[
有几个优点和缺点。[
test
优点:它是一个内置命令,因此速度更快,并且具有更多功能,例如正则表达式检查和解析(记住:man bash 是你的朋友)并且不需要转义某些操作数。
缺点:它不可移植,因为它在每个 shell 解释器中都有不同的运算符。
$?
正如术语所述,表达式是man bash
一个特殊参数,用于解析或“扩展”最后一个命令的退出状态。如果最后一个命令成功,它应该返回 true(对于 Bash 为 0),因此$?
将是一个数字零;在其他情况下,将是命令返回的数字。例如,此命令行将显示尝试查找文件$?
时返回的错误值:ls
a-nonexistent-file.txt
ls a-nonexistent-file-txt ; echo $?
Bash 作为一种编程语言,有很多怪癖和特性;学习 Bash 手册是成功之路。
[抱歉,我的答案似乎重复了,但其他答案并不具体,也没有回答所有的问题(没有冒犯的意思;我在那里学到了一些不相关的东西)。]