Bash: не удается запустить программу, созданную с помощью make в Linux

Я хочу собрать свою программу с помощью make, а затем запустить созданный исполняемый файл с помощью сценария bash, но bash не может найти исполняемый файл, хотя он был создан, и я могу запустить его вручную. Проблема существует только в Linux Mint 19 в Gnome-терминале. Обновлено: точное сообщение об ошибке: «/path/to/my/executable: нет такого файла или каталога»

У меня есть кроссплатформенный проект, в котором мне нужно запустить cmake, затем собрать проект и, наконец, запустить созданный исполняемый файл. У меня есть bash-скрипт для автоматизации процесса: Обновлено: это только та часть, которая вызывает проблемы;)

for TASK in $@; do
    if [[ $TASK == "make" ]]; then
        call cmake here, this creates a .sln or a make file
    elif [[ $TASK == "build" ]]; then
        if  [[ $OS == 'CYGWIN_NT-10.0' ]]; then
            MSBuild.exe "./build/debug/myproject.sln"
        elif [[ $OS == 'Linux' ]]; then
            cd ./build/debug/ && make
        else
            error...
        fi
    elif [[ $TASK == "run" ]]; then
        if  [[ $OS == 'CYGWIN_NT-10.0' ]]; then
            ./build/debug/Debug/program.exe
        elif [[ $OS == 'Linux' ]]; then
            ./build/debug/program
        else
            error...
        fi
    else
        error...
    fi
done

Вызов «./script.sh make build run» должен, например, вызвать cmake для создания файлов сборки, затем вызвать программу сборки (make в Linux или msbuild в Windows), а затем запустить созданный исполняемый файл. Это отлично работает на Windows 10 в терминале cygwin. В Linux вызов «./script.sh build run» завершается ошибкой, так как не удается найти исполняемый файл. Однако "./script.sh build && ./build/debug/program" прекрасно работает. Удивительно, но «./script.sh build && ./script.sh run» работает так, как ожидалось. Почему это? Есть ли ошибка в скрипте bash? И почему это работает на Cygwin, но не на Linux Mint?

Вставить фактическое сообщение об ошибке? Кстати, это нет настоящий скрипт, я почти уверен, что call cmake here, this creates a .sln or a make file не работает ;)

tink 30.05.2019 11:38

Если вы разрабатывали сценарий для Windows, EOL, вероятно, является первой проблемой. См. также Как использовать Дос2Юникс?, Как использовать Шеллчек, Как отлаживать bash-скрипт? (U&L.SE), Как отлаживать bash-скрипт? (SO), Как отлаживать bash-скрипт? (AskU), Отладка Bash-скриптов и т. д.

jww 30.05.2019 11:41

Конструкция if [[ TASK == .. ]]; ...; elif [[ TASK == ...; elif [[ TASK ... отчаянно хочет быть заменена утверждением case.

William Pursell 30.05.2019 11:52

Какова первая строка вашего сценария оболочки и/или как вы ее вызываете? Если вместо #!/bin/sh написано #!/bin/bash, то это ваша проблема. Вы написали сценарий, который явно использует не-POSIX, нестандартные расширения, которые существуют только в оболочке bash. Если вы используете #!/bin/sh, то он не будет работать ни в одной системе, где /bin/sh на самом деле не является bash (что верно, например, для всех систем Debian и Ubuntu).

MadScientist 30.05.2019 18:18

конечно, это не весь сценарий, а только та его часть, которая вызывает проблемы. Я подумал, что было бы хорошо максимально упростить ;)

churill 31.05.2019 10:02

Добавлю уточнений, спасибо за подсказку! И спасибо @WilliamPursell за совет использовать оператор case :)

churill 31.05.2019 10:21

@jww я использую его на cygwin bash, который также использует LF вместо CRLF. Если бы проблема заключалась в концах строк, скрипт вообще не запустился бы.

churill 31.05.2019 10:29

@MadScientist я использую #!/bin/bash нет проблем;)

churill 31.05.2019 10:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
144
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, я решил это. Задавать вопросы, кажется, первый шаг к поиску решения. Проблема, похоже, в том, что вызов "./script.sh build run" сначала оценивает команду сборки "cd ./build/debug/ && make". Я думал, что такие команды будут порождать новую вложенную оболочку, где затем оцениваются команды cd и make, а затем оболочка продолжит работу в исходном рабочем каталоге. Судя по всему этого не происходит и рабочий каталог исполняемого скрипта меняется на "./build/debug". Следующая команда «run» пытается выполнить «./build/debug/program», но, поскольку текущий рабочий каталог изменен, она по существу ищет «./build/debug/build/debug/program», которого не существует. я добавил строку

cd ../../

к коду команды сборки. Теперь это выглядит так

...
elif [[ $OS == 'Linux' ]]; then
    cd ./build/debug/ && make
    cd ../../
else
...

Я не знаю точно, почему, но в Linux это работает именно так.

cd не порождает подоболочку, а && не порождает подоболочку. Если вы хотите создать подоболочку, вы можете использовать (). Итак, если вы напишете (cd ./build/debug && make), вы получите желаемое поведение. В качестве альтернативы, если вы знаете, что используете GNU make, вы можете использовать make -C build/debug и вообще избегать cd.
MadScientist 31.05.2019 14:36

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