bash, тире и сравнение строк
-
11-09-2019 - |
Вопрос
Я пытаюсь сравнить две строки в простом сценарии оболочки.я использовал /bin/sh
вместо /bin/bash
, и после бесчисленных часов отладки выяснилось, что sh (на самом деле это тире) не может обработать этот блок кода:
if [ "$var" == "string" ]
then
do something
fi
Что такое переносимый способ сравнения строк с помощью /bin/sh
?Я знаю, что всегда могу сделать обратное, используя !=, но мне нужен более чистый и переносимый способ.
Решение
dash
это очень строгая оболочка POSIX, если она работает в dash
почти наверняка это будет работать в другой оболочке POSIX.
Пытаться:
if [ "$var" = "string" ]
then
some_command
fi
Другие советы
Почему вообще существует вероятность того, что ваш скрипт будет запущен «не той» оболочкой?Я думаю, вы могли бы сделать это обязательным условием вашего продукта, используя стандартную строку sh-bang в верхней части вашего скрипта:
#!/bin/bash
Даже если пользователь использует другая оболочка, другие оболочки, как правило, все еще существуют, а если нет, просто жалуйтесь и заявляйте, что они являются предварительным требованием.
Точно так же, как определенный уровень ядра или наличие awk может быть предварительным требованием.
Что касается вашего конкретного вопроса, я считаю, что оба sh
и bash
разрешить использование одного знака '=" для сравнения строк - это поведение POSIX:
if [ "a" = "a" ] ; then
echo yes
fi
yes
Использовать =
вместо ==
.Сравнения обрабатываются с помощью test(1). /usr/bin/[
обычно это ссылка на /usr/bin/test
.Единственная разница в том, что если вы используете [
в сценарии оболочки, ]
также требуется.
Обратите внимание, что в bash есть встроенная функция test
/[
, поэтому он на самом деле не использует /usr/bin/test
.
Уже опубликованные ответы, безусловно, верны, но, возможно, стоит отметить, что иногда расширение параметров может служить той же цели, возможно, с некоторой дополнительной гибкостью.
% p() { printf 'notvar = %b\n' "${notvar##"${string1}"}${string2}" ; }
% string1='some stuff about things\c'
% string2='some different stuff maybe'
% notvar="$string1" p
> 'some different stuff maybe'
% notvar="$string2" p
> 'some stuff about things'
Итак, вышеизложенное не является сверхполезным как таковое, но также учтите, что вы можете использовать аналогичные методы для тестирования переменных в документах, встроенных присвоений переменных, если это необходимо (в некоторой степени...), или даже просто как более короткий (и быстрый!) способ написать первое заявление.
[ ! "${var##"string"}" ] && _MATCH || _NOMATCH
Или даже...
[ ${#var#*"${s=string}"} -lt ${#var} ] && _SUB_STRING_TEST=TRUE
Возможно даже...
% p() { printf '%s is %s of %s' "$2" "${var_chk-not}" "$1"
> }<<HEREDOC
> ${in="${1##*"${2}"*}"}
> ${in:-
> ${in="${1##"${2}"}"}
> ${in:-${var_chk=all}
> ${var_chk=some}
> }
> HEREDOC
%
ты можешь использовать awk
awk 'BEGIN{
string1="test"
string2="tes1t"
if(s1==s2){
print "same string"
}else{
print "not same"
}
}'