Я проверял скрипт оболочки и заметил следующую команду - exec. команда exec выполняет cmdline, но мне интересно, что здесь делает команда :-/bin/bash.
cmdline="$@"
exec ${cmdline:-/bin/bash}
Здесь есть три основные вещи:
$@ - специальная переменная оболочки, которая расширяется до всех аргументов командной строки скрипту ${cmdline:-/bin/bash} является одной из структур расширения параметров; если переменная cmdline не установлена или пуста, вся часть ${} заменяется на все, что приходит после знака -, в данном случае /bin/bash; это своего рода короткий оператор if или тройной оператор в других языках программирования (не совсем, но достаточно хороший для сравнения). exec используется для создания процесса, который будет обходить PID текущего процесса, т. е. просто замените процесс скрипта с тем, что было внутри ${}. Вводя все это вместе, код просто принимает аргументы командной строки и запускает их, и если для скрипта нет аргументов командной строки, вы получаете интерактивную оболочку bash. Обратите внимание, что вы также можете передавать опции exec, упомянутые в документации, - сравнить ./exec_script.sh -c env и ./exec_script.sh env.
Сам подход может показаться запутанным, но часто встречается этот подход с exec в сценариях оболочки - скрипт настраивает среду и проверяет переменные перед тем, как организовать все, чтобы запустить фактическую команду. Разница здесь заключается в том, что в команде сценариев оболочки установлено значение - скрипт-оболочка обычно устанавливает среду и аргументы для запуска только одной конкретной программы.
В отличие от этого сценарий нацелен на запуск любого пользователя, который помещается в командной строке , И это имеет проблемы сценарии оболочки - заданные аргументы командной строки, содержащие специальные символы, команда, которую вы намереваетесь запустить, может сломаться. Вот что я имею в виду:
# This is how it's supposed to work
$ printf 'one%stwo' $'\t'
one two
# This is how it works with unquoted parameter expansion
$ ./exec_script.sh printf 'one%stwo' $'\t'
onetwo
Представьте, если вы пытаетесь использовать этот скрипт для запуска my_cool_command filename$'\t'with$'\t'tabs.txt; в лучшем случае - командные перерывы, но если у вас также есть файл filenamewithtab.txt в вашей текущей папке, my_cool_command будет работать с совершенно неправильным файлом. И расширение котировки параметров тоже не помогает, потому что тогда он ломается:
$ ./exec_script.sh printf 'one%stwo' $'\t'
./exec_script.sh: line 4: exec: printf one%stwo : not found
Вот соответствующая часть о расширении параметра из bash (версия 4.3):
$ {parameter: -word} Используйте значения по умолчанию. Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра заменяется.Раздел «Специальные параметры»:
$ {parameter: -word}
@ Развернуть до позиционных параметров, начиная с один. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. То есть «$ @» эквивалентно «$ 1» «$ 2» ... Если двойное кавычное разложение происходит внутри слова, разложение первого параметра соединяется с начальной частью исходного слова, а разложение последнего параметра соединяется с последней частью исходного слова. Когда нет позиционных параметров, «$ @» и $ @ не изменяются ни к чему (т. Е. Они удаляются).
exec [-cl] [-a name] [команда [arguments]] [d17 ] Использовать значения по умолчанию. Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра будет заменено.В разделе «Команды встроенной оболочки»:
Здесь есть три основные вещи:
$@ - специальная переменная оболочки, которая расширяется до всех аргументов командной строки скрипту ${cmdline:-/bin/bash} является одной из структур расширения параметров; если переменная cmdline не установлена или пуста, вся часть ${} заменяется на все, что приходит после знака -, в данном случае /bin/bash; это своего рода короткий оператор if или тройной оператор в других языках программирования (не совсем, но достаточно хороший для сравнения). exec используется для создания процесса, который будет обходить PID текущего процесса, т. е. просто замените процесс скрипта с тем, что было внутри ${}. Вводя все это вместе, код просто принимает аргументы командной строки и запускает их, и если для скрипта нет аргументов командной строки, вы получаете интерактивную оболочку bash. Обратите внимание, что вы также можете передавать опции exec, упомянутые в документации, - сравнить ./exec_script.sh -c env и ./exec_script.sh env.
Сам подход может показаться запутанным, но часто встречается этот подход с exec в сценариях оболочки - скрипт настраивает среду и проверяет переменные перед тем, как организовать все, чтобы запустить фактическую команду. Разница здесь заключается в том, что в команде сценариев оболочки установлено значение - скрипт-оболочка обычно устанавливает среду и аргументы для запуска только одной конкретной программы.
В отличие от этого сценарий нацелен на запуск любого пользователя, который помещается в командной строке , И это имеет проблемы сценарии оболочки - заданные аргументы командной строки, содержащие специальные символы, команда, которую вы намереваетесь запустить, может сломаться. Вот что я имею в виду:
# This is how it's supposed to work
$ printf 'one%stwo' $'\t'
one two
# This is how it works with unquoted parameter expansion
$ ./exec_script.sh printf 'one%stwo' $'\t'
onetwo
Представьте, если вы пытаетесь использовать этот скрипт для запуска my_cool_command filename$'\t'with$'\t'tabs.txt; в лучшем случае - командные перерывы, но если у вас также есть файл filenamewithtab.txt в вашей текущей папке, my_cool_command будет работать с совершенно неправильным файлом. И расширение котировки параметров тоже не помогает, потому что тогда он ломается:
$ ./exec_script.sh printf 'one%stwo' $'\t'
./exec_script.sh: line 4: exec: printf one%stwo : not found
Вот соответствующая часть о расширении параметра из bash (версия 4.3):
$ {parameter: -word} Используйте значения по умолчанию. Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра заменяется.Раздел «Специальные параметры»:
$ {parameter: -word}
@ Развернуть до позиционных параметров, начиная с один. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. То есть «$ @» эквивалентно «$ 1» «$ 2» ... Если двойное кавычное разложение происходит внутри слова, разложение первого параметра соединяется с начальной частью исходного слова, а разложение последнего параметра соединяется с последней частью исходного слова. Когда нет позиционных параметров, «$ @» и $ @ не изменяются ни к чему (т. Е. Они удаляются).
exec [-cl] [-a name] [команда [arguments]]Использовать значения по умолчанию. Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра будет заменено.
В разделе «Команды встроенной оболочки»:
Здесь есть три основные вещи:
$@ - специальная переменная оболочки, которая расширяется до всех аргументов командной строки скрипту ${cmdline:-/bin/bash} является одной из структур расширения параметров; если переменная cmdline не установлена или пуста, вся часть ${} заменяется на все, что приходит после знака -, в данном случае /bin/bash; это своего рода короткий оператор if или тройной оператор в других языках программирования (не совсем, но достаточно хороший для сравнения). exec используется для создания процесса, который будет обходить PID текущего процесса, т. е. просто замените процесс скрипта с тем, что было внутри ${}. Вводя все это вместе, код просто принимает аргументы командной строки и запускает их, и если для скрипта нет аргументов командной строки, вы получаете интерактивную оболочку bash. Обратите внимание, что вы также можете передавать опции exec, упомянутые в документации, - сравнить ./exec_script.sh -c env и ./exec_script.sh env.
Сам подход может показаться запутанным, но часто встречается этот подход с exec в сценариях оболочки - скрипт настраивает среду и проверяет переменные перед тем, как организовать все, чтобы запустить фактическую команду. Разница здесь заключается в том, что в команде сценариев оболочки установлено значение - скрипт-оболочка обычно устанавливает среду и аргументы для запуска только одной конкретной программы.
В отличие от этого сценарий нацелен на запуск любого пользователя, который помещается в командной строке , И это имеет проблемы сценарии оболочки - заданные аргументы командной строки, содержащие специальные символы, команда, которую вы намереваетесь запустить, может сломаться. Вот что я имею в виду:
# This is how it's supposed to work
$ printf 'one%stwo' $'\t'
one two
# This is how it works with unquoted parameter expansion
$ ./exec_script.sh printf 'one%stwo' $'\t'
onetwo
Представьте, если вы пытаетесь использовать этот скрипт для запуска my_cool_command filename$'\t'with$'\t'tabs.txt; в лучшем случае - командные перерывы, но если у вас также есть файл filenamewithtab.txt в вашей текущей папке, my_cool_command будет работать с совершенно неправильным файлом. И расширение котировки параметров тоже не помогает, потому что тогда он ломается:
$ ./exec_script.sh printf 'one%stwo' $'\t'
./exec_script.sh: line 4: exec: printf one%stwo : not found
Вот соответствующая часть о расширении параметра из bash (версия 4.3):
$ {parameter: -word} Используйте значения по умолчанию. Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра заменяется.Раздел «Специальные параметры»:
$ {parameter: -word}
@ Развернуть до позиционных параметров, начиная с один. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. То есть «$ @» эквивалентно «$ 1» «$ 2» ... Если двойное кавычное разложение происходит внутри слова, разложение первого параметра соединяется с начальной частью исходного слова, а разложение последнего параметра соединяется с последней частью исходного слова. Когда нет позиционных параметров, «$ @» и $ @ не изменяются ни к чему (т. Е. Они удаляются).
exec [-cl] [-a name] [команда [arguments]]Использовать значения по умолчанию. Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра будет заменено.
В разделе «Команды встроенной оболочки»: