Я изучаю 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 или какого-либо другого редактора, популярного для сценариев удара?
: ${TEMPDIR:=/tmp}
Можно ли объяснить, каково это? У меня есть знание программирования C# и других языков программирования. Так можете Вы говорить мне, предполагая, что я не общий новичок при программировании, что: ключ и ключи фигурной скобки делают?
if [[ "$Line2" > "$Line1" ]]; then
[]
то же как тест. Но почему делает [[]]
несколько отличающийся?
status1=$?
что $?
?
Заранее большое спасибо.
Я использую vim для написания сценариев оболочки.
${TEMPDIR}
расширится до значения переменной с именем TEMPDIR. ${TEMPDIR:=/tmp}
будет делать то же самое, но если оно пустое (или не установлено), значение / tmp будет присвоено TEMPDIR, а также расширено.
Наличие ${TEMPDIR:=/tmp}
одного в строке приведет к его изменению, например, на. /tmp
, который попытается выполнить /tmp
как команду (что, очевидно, не удастся, поскольку вы не можете выполнить каталог). Вот почему используется команда :
(null). Команда null игнорирует все входные данные, все аргументы и абсолютно ничего не делает. Запустите help :
, чтобы увидеть описание этой встроенной команды.
См. http://mywiki.wooledge.org/BashFAQ/073 Для различных вещей, которые вы можете сделать с расширением параметра.
[[ "$line2" > "$Line1" ]]
возвращает true, если line2 сортируется после line1 (как strcmp в C).
[(команда «test») и [[(команда «new test»)) используются для оценки выражений. [[работает только в оболочках Bash, Zsh и Korn и является более мощным; [и тест доступны в оболочках POSIX.
См. http://mywiki.wooledge.org/BashFAQ/031 для определения различия между командой [
и ключевым словом [[
.
?
- это специальный параметр , который содержит состояние выхода последней выполненной команды. $?
расширяет значение этого параметра.
Кстати, если это пример из вашей книги, я бы сказал, что это плохой источник для изучения bash. Я рекомендую прочитать http://mywiki.wooledge.org/BashGuide , который также учит хорошим практикам.
Да, у вас есть отступ в Gedit. Откройте gedit и в Edit-> Preferences вы можете иметь опцию автоматического отступа.
Что касается второго пункта, то, как он говорит, предполагается, что TEMPDIR находится в /tmp
месте.
Команда :
- это встроенная команда Bash, которая ничего не делает, кроме return 0 ( правда); но в этом случае служит для оценки расширения параметра ${VAR:=VALUE}
, которое присваивает VALUE
- $VAR
, только если оно не существует. Если $VAR
(в вашем случае $TEMPDIR
) уже имеет значение, оно не изменяется. Это эквивалентно конструкции:
[[ -z "$TEMPDIR" ]] && TEMPDIR=/tmp
, т. Е. «Если $TEMPDIR
пусто, оцените команду справа (назначьте /tmp
- TEMPDIR
)».
Команда [[
является встроенной командой Bash, в то время как [
является исполняемой командой в /usr/bin/[
(а также ее эквивалентом /usr/bin/test
). Команда [[
имеет несколько плюсов и минусов против [
или test
.
Плюсы: это встроенная команда, поэтому она быстрее и имеет больше функциональных возможностей, таких как проверка и анализ регулярных выражений (помните: man bash - ваш друг).
Минусы: он не переносим, так как в каждом из интерпретаторов оболочки, где он существует, имеются разные операторы.
Выражение $?
, как гласит терминология в man bash
, является специальным параметром, который разрешает или «расширяет» до состояния выхода последней команды. Если последняя команда была успешной, она должна вернуть true (0 для Bash), поэтому $?
будет числовым нулем; в других случаях $?
будет числом, возвращаемым командой. Например, эта командная строка ls
/ echo
покажет значение ошибки, возвращенное ls
, пытающимся найти файл an-nonexistent-file.txt
:
ls an-nonexistent-file-txt ; echo $?
Bash в качестве программирования язык имеет много причуд и особенностей; изучение руководства по Bash - путь к успеху.
[Извините за очевидный повторяющийся ответ, но остальные были неспецифичными и не отвечали на все вопросы в том виде, в котором они были заданы (не означает оскорбление; я узнал там пару несвязанных вещей).]