![Могу ли я использовать shebang, чтобы иметь исходный файл в текущей среде bash?](https://rvso.com/image/89150/%D0%9C%D0%BE%D0%B3%D1%83%20%D0%BB%D0%B8%20%D1%8F%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20shebang%2C%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%B8%D0%BC%D0%B5%D1%82%D1%8C%20%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9%20%D1%84%D0%B0%D0%B9%D0%BB%20%D0%B2%20%D1%82%D0%B5%D0%BA%D1%83%D1%89%D0%B5%D0%B9%20%D1%81%D1%80%D0%B5%D0%B4%D0%B5%20bash%3F.png)
У меня есть растущая коллекцияскриптыкоторыйследует искать, а не запускать. В данный момент у них есть притон
#! /bin/cat
но я бы предпочел, чтобы они были переданы в bash при запуске, так же, как я это сделал
$ . /path/to/script.sh
или
$ source /path/to/script.sh
Но есть .
ли source
встроенные функции bash, так возможна ли альтернативная строка shebang для таких скриптов?
решение1
Нет. К тому времени, как в игру вступает shebang, вы уже проиграли. Shebang применяется, когда процесс exec()
'd, и обычно это происходит после разветвления, так что вы уже находитесь в отдельном процессе. Shebang читает не оболочка, а ядро.
решение2
She-bang интерпретируется ядром при выполнении команды, а не оболочкой. Так что к тому времени уже слишком поздно.
Вместо этого вы можете сделать это:
#! /bin/echo Please run (from a Bourne-like shell): .
Или:
#! /bin/sed 2,5!d;s/^#.//
# This script must be sourced from within a shell
# and not executed. For instance with:
#
# . path/to/that/script
rest of the script
Чтобы сообщить пользователю, что он сделал неправильно.
Что должно работать на Linux. Замените все пробелы, кроме первого, на один из не-ASCII пробельных символов (например, U+00A0, U+2006...) на некоторых других ОС. Возможно, вам придется адаптировать путь к утилитам echo
или sed
.
решение3
Как говорит пользователь @muru, это невозможно сделать, поскольку вы уже покинули сеанс оболочки, когда дошли до строки #!
-.
Однако в зависимости от того, что делают ваши файлы оболочки, может быть и другое решение.
Я предполагаю, что они устанавливают переменные среды, которые вы используете для какого-то проекта.
Давайте назовем проект subtool
(потому что это проект, который у меня есть). Тогда у вас может быть скрипт, который настраивает среду оболочки для проектов, project-env
например:
#!/bin/bash
PROJECT="$1"
PROJECT_ROOT="$HOME/projects/$PROJECT"
cd "$PROJECT_ROOT" || exit 1
source "$PROJECT.env"
export PS1="[$PROJECT: \W] \$ "
exec bash -i
Бежать с:
$ ./project-env subtool
Это автоматически переместит cd
вас в указанную подпапку проекта $HOME/projects
, прочитает файл среды проекта, названный subtool.env
в данном случае (в котором вы инициализируете переменные), выдаст вам приглашение командной строки для проекта и оставит вас в интерактивном bash
сеансе:
[subtool: subtool] $
Когда работа будет сделана, просто exit
.
Это также дает преимущество изоляции среды проекта от вашего «обычного» сеанса входа в систему и от других проектов.
решение4
То, что вы хотите сделать в этих .'ed скриптах, изменяет процесс оболочки; поэтому вам нужно вызывать их из процесса оболочки; что означает либо псевдонимы, либо их более мощные братья функции оболочки. Это означает, что вам нужно сделать некоторую настройку в .profile или эквиваленте.
Трюк с псевдонимом довольно прост: alias mytool1=". /my/library/mytool1.sh"
Можете ли вы прочитать все в начале? .profile: . /my/library/define_tools.sh
define_mytools.sh: mytool1() { ... содержимое mytool1.sh ... } mytool2() { ...; }