Если/Еще в сценарии оболочки бросает ошибки в Ubuntu для Windows

Вот является пример простым сценарием оболочки:

#!/usr/bin/env bash
if [ 1 == 1 ]; then
echo "Something"
fi

Когда я выполняю это

sh ./test.sh

Я добираюсь:

./test.sh: 4: ./test.sh: Syntax error: "fi" unexpected (expecting "then")

Это, кажется, не распознает 'затем', я имею там. Какая-либо подсказка, относительно почему? Это - Ubuntu для Windows в случае, если та часть имеет значение.

Выполнение сценариев оболочки в целом не является проблемой, это просто, кажется, борется с если/еще.

2
задан 16 November 2017 в 12:11

2 ответа

Здесь существует две проблемы. Во-первых, в то время как у Вас есть удар вызова строки хижины, Вы выполняете сценарий как sh script.sh. Строка хижины уже указывает интерпретатор для этого сценария. Так, просто сделайте исполняемый файл сценария:

chmod a+x ./test.sh

И затем выполненный это:

./test.sh

С другой стороны, выполните его с ударом явно:

bash ./test.sh

Это заставит его работать с bash вместо sh который является более ограниченной оболочкой и не понимает ==. Который приносит нам к второй проблеме и почему это перестало работать. Странно достаточно Вы хотите eq или =, нет ==. Оператор, который тестирует числовое равенство в сценариях оболочки POSIX (sh совместимая POSIX оболочка), -eq в то время как тот, который тестирует строковое равенство, = и == не вещь.

Так, если Вы хотите, чтобы Ваш сценарий был выполнен sh, измените его на:

if [ 1 = 1 ]; then
    echo "Something"
fi

Который проверяет что строка 1 совпадает со строкой 1, или выдерживать сравнение численно, используйте:

if [ 1 -eq 1 ]; then
    echo "Something"
fi

Кроме того, у Вас есть другая проблема. Я могу только воспроизвести определенную ошибку, в которую Вы входите dash если я добавляю a \r после then. Это - классическая проблема при перемещении между Windows и Linux. В то время как Linux использует \n как символ конца строки, Windows заканчивает свои строки \r\n. Это \r символ не видим пользователю, но это там и путает сценарий. Так, можно удалить его с:

sed -i 's/\r//' ./test.sh

И в будущем, используйте надлежащий текстовый редактор для записи сценариев. Или тот, который работает в системе WSL или той, которая может, по крайней мере, быть настроена для не добавления \r к концам его строк.

6
ответ дан 2 December 2019 в 01:32

Давайте сохраним это простым:

  • sh не bash на Ubuntu (см. это для ссылки).

  • [ команда, то же как test команда. Это не поддерживает == для арифметического сравнения. Использовать -eq вместо этого. Это - одна из утилит, указанных стандартами POSIX, следовательно работы в обоих bash и dash.

    if [ 1 -eq 1 ];
    then
        echo "it works!"
    fi
    
  • bash имеет (( который называют арифметическим расширением. Это поддерживает ==. Эта функция, по-видимому, одолжена от ksh оболочка.

    $ var=25 bash -c 'if((var==5)); then echo Y;else echo "N";fi'      
    N
    $ var=25 bash -c 'if((var==25)); then echo Y;else echo "N";fi' 
    Y
    
  • Несмотря на то, что dash не поддерживает if (()), в любой оболочке $(( будет работать, потому что это получает мандат по стандарту POSIX. Беря только функции, которые характерны для обеих оболочек, мы могли сделать что-то вроде этого при тихом использовании == для сравнений:

    
    $ var=25 dash -c 'if [ $((var==25)) -eq 1 ];then echo Y; else echo N;fi'
    Y
    $ var=25 dash -c 'if [ $((var==5)) -eq 1 ];then echo Y; else echo N;fi' 
    N
    
  • Мы могли выбросить if оператор в целом и использование case вместо этого (отмечают, что статус возврата соответствует C, не, окружают поведение, т.е. верный 1, и ложь 0, не наоборот как в оболочке):

    $ dash -c 'case $((1==1)) in 1) echo "equal";; 0) echo "not equal";;esac'                                                                                                
    equal
    $ dash -c 'case $((1==2)) in 1) echo "equal";; 0) echo "not equal";;esac'                                                                                                
    not equal
    
  • или мы можем стать подлыми с (ab) использование арифметического расширения:

    $ var=25 dash -c '_0(){ false;}; _1(){ true;}; if "_$((var==25))" ; then echo Y; else echo N; fi'
    
2
ответ дан 2 December 2019 в 01:32

Другие вопросы по тегам:

Похожие вопросы: