Белое пространство (на самом деле, отсутствие кавычек в ваших переменных) было только частью проблемы.
Вы не можете просто так передать переменную через sed
, это не работает. Точнее, это не передача значения "$VARIABLE" через sed
, оболочка попытается выполнить значение "$VARIABLE" и передать вывод этого через sed
. BTW, это не ошибка - это полезно, если $VARIABLE содержит допустимую команду, например ls
или rsync
или что-то еще.
Также, если вы хотите присвоить результат команды или конвейера переменной, вам нужно окружить эту команду/конвейер символом $()
.
Итак, чтобы изменить переменную с помощью sed
, вам нужно сделать примерно следующее:
VARIABLE=$(printf '%s' "$VARIABLE" | sed 's/[0-9]*//g')
Вы могли бы использовать echo
вместо printf
, но echo будет интерпретировать и действовать в отношении определенных последовательностей символов в $VARIABLE (например. например, \t
, \n
, \r
и т.д.), а printf
- нет. Вы встретите много примеров с использованием echo
... замените их на printf '%s'
, это гораздо безопаснее.
Вот как отлаживать что-то подобное. У меня есть упрощенная версия вашего скрипта.
$ cat var_dumper.bash
#!/bin/bash
var1=1
var2=2
if [ ! "$var1" > "$var2" ]; then
echo "I'm inside the if/then"
fi
И мы запускаем его:
$./var_dumper.bash
$ ls
var_dumper.bash 2
Итак, мы видим, что ваш 2
отображается в виде файла. Это ваша проблема.
Чтобы отладить сценарий оболочки, я всегда начинаю с -x
переключения на Bash. Вы можете запустить свой скрипт следующим образом:
$ bash -x./var_dumper.bash
+ var1=1
+ var2=2
+ '[' '!' 1 ']'
Это говорит нам о том, где он терпит неудачу. Условие if
. Так что же с этим не так? Ну, первая подсказка должна быть >
. Это оператор перенаправления в других случаях использования в Bash, так что это, вероятно, создает записываемый файл.
Итак, давайте переформулируем ваш пример в один исполняемый файл:
$ var1=1 var2=2 [ "$var1" > "$var2" ] && echo success || echo failure
success
Следующей подсказкой должно быть, почему он возвращает успех, 1 не больше, чем 2. Итак, мы гуглим и обнаруживаем, что для сравнения целых чисел в Bash вы не используете оператор >
, вы на самом деле предполагается использовать этот:-gt
.
$ var1=1 var2=2 [ "$var1" -gt "$var2" ] && echo success || echo failure
failure
И поскольку вы изначально хотели, чтобы оно было инвертировано, мы могли бы вернуть !
обратно в:
$ var1=1 var2=2 [ ! "$var1" -gt "$var2" ] && echo success || echo failure
success
И это работает. Таким образом, ваше исправленное if
утверждение будет выглядеть так:
if [ ! "$var1" -gt "$var2" ]; then
echo "I'm inside the if/then"
fi
>
В вашем сценарии вы использовали if [.... ]
. Эта форма if/then является версией, совместимой с POSIX. Этот не поддерживает оператор >
. Форма, которая поддерживает это, такова: if [[.... ]]
.Версия с двойными скобками — это более эффективная команда расширенного теста .
Так что в качестве альтернативы:
$ cat var_dumper.bash
#!/bin/bash
var1=1
var2=2
if [[ ! "$var1" > "$var2" ]]; then
echo "I'm inside the if/then"
fi
Также подойдет:
$ bash -x var_dumper.bash
+ var1=1
+ var2=2
+ [[ ! 1 > 2 ]]
+ echo 'I'\''m inside the if/then'
I'm inside the if/then
Не используйте > в цифровом тесте. Потому что это оператор перенаправления.
Его выполнение всегда верно (, если файл записан):
$ if [ 2 > 30000 ]; then echo OK; else echo NO; fi
OK
$ ls
$ 30000
$ rm 30000
И файл 30000 был написан.
Цифрового теста не было, но запись в файл вернула истину
$ mkdir tmp
$ chmod -w tmp
$ cd tmp
$ if [ 2 > 30000 ]; then echo OK; else echo NO; fi
-bash: 30000: Permission non accordée
NO
$ cd..
$ rmdir tmp
Используйте -gt:
$ if [ 2 -gt 30000 ]; then echo OK; else echo NO; fi
NO
$ ls