Сценарии оболочки - какое слово сначала в алфавитном порядке? - PullRequest
4 голосов
/ 24 января 2012

Как вы можете проверить, какие слова в алфавитном порядке между двумя словами? Например в коде

#!/bin/bash

var1="apple"
var2="bye"

if [ $var1 \> $var2 ]
then
echo $var1
else
echo $var2
fi

Я хочу, чтобы он напечатал яблоко, так как яблоко идет раньше по алфавиту, но оно работает не так, как задумано. Что я делаю не так?

Ответы [ 3 ]

9 голосов
/ 24 января 2012

То, что вам нужно сделать для решения насущной проблемы, - это изменить смысл вашего утверждения, поскольку оператор «меньше чем» равен <, а не >.

.правильно:

if [ $var1 \< $var2 ]

В качестве альтернативы вы можете использовать вариант [[, для которого не требуется экранирование:

if [[ $var1 < $var2 ]]

Я предпочитаюпоследнее, потому что:

  1. выглядит лучше;
  2. вариант [[ гораздо более выразительный и мощный.
4 голосов
/ 24 января 2012

Вы захотите использовать конструкцию [[ ]] и распечатать одну, которая меньше , другую

#!/bin/bash

var1="apple"
var2="bye"

if [[ $var1 < $var2 ]]; then
  echo $var1
else
  echo $var2
fi
1 голос
/ 24 января 2012

Похоже, вы страдаете от двух неправильных представлений о (bash) сценариях оболочки.

Во-первых, строка if [ $var1 > $var2 ] then echo ... синтаксически неверна, и вы должны вставлять примерные команды или код, а не пытаться повторновведите их по памяти.Было бы хорошо, если бы вы сказали if [[ "$var1" > "$var2" ]]; then ... или if [ "$var" \> "$var2" ]; then ....

. Обратите внимание, что [[ является условным выражением, относящимся к bash, тогда как [(одиночная скобка) представляет встроенную в оболочку реализацию /usr/bin/[ (псевдоним для /usr/bin/test).

Старая команда [ (test) имеет гораздо больше ограниченных возможностей, чем поддержка [[ в bash.Он поддерживает только -lt, -eq ... и другие целочисленные сравнения и различные длины файлов и значений (-z' and -n ) and other tests. It has no support for lexical/string or pattern (regex nor glob) comparisons. The bash built-in for [supports a number of the [[``расширения, но, как показано, некоторые из них должны быть явно экранированы от устаревшего синтаксического анализа.

Также обратите внимание, что опасно использовать барные разыменования $var (против "$var" с кавычками). Если значениеназначенный на var имеет встроенные пробелы или различные другие операторы, которые могут быть связаны с переключателями для команды test.

Также вам необходим ; для отделения команды if от then clause.

Попытка написания сценариев оболочки, как если бы shell была обычным языком программирования, приведет вас к некоторой путанице такого рода. Такие оболочки, как bash, имеют относительно небольшой синтаксис и встроенныепо функциональности, и это в основном связано с выполнением команд. В ранних версиях UNIX оболочка не имела встроенных тестов и полностью полагалась на внешнюю команду test.Все больше и больше функций было встроено в оболочку, часто через псевдонимы к этим старым командам (/usr/bin/[' is literally a link to the / usr / bin / test command and the shell built-ins for [and test` являются внутренними псевдонимами друг друга и реализованы как (в основном?)совместим со старыми (и все еще существующими) внешними двоичными файлами.

Аналогично, все арифметические операции в ранних оболочках Bourne выполнялись с использованием внешних команд, таких как /usr/bin/expr.В оболочку Korn и Bash добавлены выражения $ ((...)) и let и ((...)) для оценки арифметических выражений изнутри оболочки без поддержки внешних команд.

Другие примеры касаются поддержки массивов (declare) и расширение параметров ${var#...} различные другие формы.

Как правило, лучше избегать большинства таких функций или использовать их экономно, в качестве результирующих сценариев, поскольку они становятся все менее переносимыми по мере их использования ... исинтаксические махинации быстро сокрушают код.В какой-то момент лучше всего использовать Perl, Python, Ruby или какой-либо язык программирования / сценариев общего назначения для выполнения общей работы по программированию и использовать оболочку для целей, для которых она была разработана ... в качестве клея вокруг внешних команд, для маршалинга данных ипеременные в и из этих внешних команд / процессов.

...