понимание терминологии .sh файлов и cmake

Я пытаюсь использовать cmake и OpenGL для изучения компьютерной графики, и в учебник включен файл run.sh, предназначенный для компиляции / сборки программ cpp. Вот код:

#!/bin/bash #calls cd build #cmake .. -DSRC && make argument EMBEDDED=`echo $2` DIRECTORY=`echo $1 |cut -d'/' -f1` FILENAME=`echo $1 |cut -d'/' -f2 |cut -d'.' -f1 | sed -e "s|/|_|g"` TARGET=${FILENAME} mkdir build cd build rm bin/${TARGET} cmake .. -DSRC=../$1 make VERBOSE=1 bin/${TARGET} 

Насколько я понимаю, mkdir создает каталог для сборки, затем мы «входим» в этот каталог, удаляем что-то из предыдущей сборки, создаем реальный файл, я понятия не имею, что делает «VERBOSE = 1», и тогда я думаю, что мы получить доступ к исполняемому файлу в последней строке.

Я не понимаю, что делает средний блок кода, начинающийся с EMBEDDED, и я не уверен в том, что делает третий комментарий “#cmake …”. Я использую файлы cpp и думаю, что должен передать файл в качестве аргумента командной строки вместе с ./run.sh.

слишком сложное задание

 EMBEDDED=`echo $2` 

Это берет второй аргумент сценария и выполняет разделение и глобус над ним (удивительно!) И передает результат этого echo а затем назначает результат того, что делает echo (которое из-за ползучего фатуризма может не быть эхо ) EMBEDDED . Это, вероятно, более разумно написано с использованием простого

 EMBEDDED=$2 

оператор присваивания.

слишком сложное определение компонента пути к файлу

 DIRECTORY=`echo $1 |cut -d'/' -f1` 

Это может быть написано более тщательно, используя команду dirname(1) с также "" чтобы исключить разделение и глобус POSIX, так как, вероятно, не требуется каких-либо результатов от (сюрприз!) Разбиения и глобинга, запускающих то, что назначено DIRECTORY .

 DIRECTORY=`dirname "$1"` 

Тем не менее, dirname и cut -d'/' -f1 не совпадают, если только входные данные не являются somedirectory/somefile . Кто-то должен был бы понять входные данные для кода, чтобы знать, можно ли сделать упрощение для dirname . Ожидаемые входные данные не документированы в сценарии, размещенном в вопросе – они где-нибудь задокументированы?

В соответствующей заметке есть команда basename(1) которая может помочь с

 FILENAME=`echo $1 |cut -d'/' -f2 |cut -d'.' -f1 | sed -e "s|/|_|g"` 

хотя кажется, что этот конвейер с cut -d'.' -f1 cut -d'.' -f1 пытается получить prefix из prefix.whatever , и я понятия не имею, для чего предназначен sed -e "s|/|_|g" , так как / не может появляться в именах файлов. Если в передаваемом аргументе есть _ было бы разумнее передать их как _ и не добавлять дополнительный код для изменения / в _ . Так что, вероятно, вышесказанное можно было бы

 FILENAME=`basename "$1" | cut -d'.' -f1` 

ненужно опасные команды

 mkdir build cd build rm bin/${TARGET} 

Эта последовательность может создавать или не создавать каталог build а затем будет пытаться удалить различные вещи из нового каталога build или в случае сбоя родительского объекта этого. Это небрежно и неопределенно. И под разными вещами я подразумеваю, что ${TARGET} будет расширен с помощью POSIX-оболочки и глобуса, поэтому может содержать совершенно неожиданные имена файлов – к счастью, rm не является обычным «о да, насчет файловой системы, которую вы только что потеряли» rm -rf так Веселье будет ограничено различными (все еще удивительными!) именами файлов, возможно, из неправильного каталога.

(Некоторые могут утверждать, что вместо нестабильных и подверженных ошибкам сценариев оболочки следует использовать управление конфигурацией или, по крайней мере, защищенные команды , но здесь мы …)

 [ -d build ] || { mkdir build; [ -d build ] || exit 1; } cd build || exit 1 rm bin/"${TARGET}" cmake .. -DSRC=../"$1" && make VERBOSE=1 && bin/"${TARGET}" 

Здесь build – это каталог, созданный как каталог, или при сбое сценария происходит сбой (вы также можете добавить собственное сообщение об ошибке, хотя mkdir обычно создает шум). Это не атомарно в том смысле, что что-то еще может touch build между проверкой -d и последующим mkdir , поэтому другой подход состоит в том, чтобы «создать каталог и затем проверить результат, чтобы увидеть, был ли это сбой (не в порядке) или EEXIST в каталоге (хорошо). cd также проверяется на наличие сбоев, а $TARGET указывается в кавычках, чтобы предотвратить POSIX-разбиение и глобирование.