针对新手的一些 Bash 问题

针对新手的一些 Bash 问题

我正在学习 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

问题:

  1. 首先,如何在 Gedit 中缩进代码?我从一本书中复制并粘贴了代码,但它不会自动缩进代码。您通常使用 Gedit 或任何其他流行的编辑器来编写 bash 脚本吗?

  2. : ${TEMPDIR:=/tmp}
    你能解释一下这是什么吗?我有 C# 和其他编程语言的编程知识。那么你能告诉我,假设我不是编程新手,这个:键和花括号键有什么用吗?

  3. if [[ "$Line2" > "$Line1" ]]; then
    []与测试相同。但是为什么会[[]]有所不同?

  4. status1=$?
    什么是$?

提前谢谢了。

答案1

  1. 我使用 vim 编写 shell 脚本。

  2. ${TEMPDIR}将扩展为名为 TEMPDIR 的变量的值。${TEMPDIR:=/tmp}将执行相同操作,但如果它为空(或未设置),则值 /tmp 将被分配给 TEMPDIR,并且也会扩展。

    单独${TEMPDIR:=/tmp}在一行上,将导致它被更改为例如,它将尝试作为命令/tmp执行(这显然会失败,因为您无法执行目录)。这就是使用 (null) 命令的原因。null 命令忽略所有输入、所有参数,并且绝对不执行任何操作。运行以查看该内置命令的描述。/tmp:help :

    http://mywiki.wooledge.org/BashFAQ/073使用参数扩展可以做各种事情。

  3. [[ "$line2" > "$Line1" ]] 如果 line2 排在 line1 之后 (类似 C 语言中的 strcmp),则返回 true。

    [(“test” 命令) 和 [[ (“new test” 命令) 用于评估表达式。[[ 仅适用于 Bash、Zsh 和 Korn shell,并且功能更强大;[ 和 test 在 POSIX shell 中可用。

    http://mywiki.wooledge.org/BashFAQ/031[命令和关键字之间的区别[[

  4. ?特殊参数它保存了最后执行的命令的退出状态。 $?扩展该参数的值。

顺便说一句,如果这是你书中的一个例子,我会说这是一个学习 bash 的糟糕资源。我建议阅读http://mywiki.wooledge.org/BashGuide这也教会了我们良好的做法。

答案2

是的,您在 Gedit 中有缩进。打开 gedit 并在“编辑”->“首选项”中,您可以使用自动缩进选项。在此处输入图片描述

关于第二点,它的意思就像假设 TEMPDIR 位于/tmp位置。

答案3

  1. 要在 Gedit 中缩进代码,请按Tab键,然后按Shift-Tab取消缩进。您需要的所有信息和热键列表位于gedit 的 Gnome 文档部分

  2. :命令是内置的 Bash 命令,除了返回 0(真)外不执行任何操作;但在这种情况下,它用于允许对参数扩展进行评估${VAR:=VALUE},只有当它不存在时才将其分配给。如果VALUE(在您的情况下)已经有一个值,则不会对其进行修改。它相当于构造:$VAR$VAR$TEMPDIR

    [[ -z "$TEMPDIR" ]] && TEMPDIR=/tmp
    

    即,“如果$TEMPDIR为空,则评估右侧的命令(分配/tmpTEMPDIR)”。

  3. [[命令是内置的 Bash 命令(和 一样[test它们也有可执行等效命令)。与或相比,该命令[[有几个优点和缺点。[test

    优点:它是一个内置命令,因此速度更快,并且具有更多功能,例如正则表达式检查和解析(记住:man bash 是你的朋友)并且不需要转义某些操作数。

    缺点:它不可移植,因为它在每个 shell 解释器中都有不同的运算符。

  4. $?正如术语所述,表达式是man bash一个特殊参数,用于解析或“扩展”最后一个命令的退出状态。如果最后一个命令成功,它应该返回 true(对于 Bash 为 0),因此$?将是一个数字零;在其他情况下,将是命令返回的数字。例如,此命令行将显示尝试查找文件$?时返回的错误值:lsa-nonexistent-file.txt

    ls a-nonexistent-file-txt ; echo $?
    

Bash 作为一种编程语言,有很多怪癖和特性;学习 Bash 手册是成功之路。

[抱歉,我的答案似乎重复了,但其他答案并不具体,也没有回答所有的问题(没有冒犯的意思;我在那里学到了一些不相关的东西)。]

相关内容