Я использую скрипт bash в терминале , поэтому при выходе
set -o errexit
убивает мой терминал, который крайне раздражает, потому что я должен закрыть терминал, открыть другой и сбросить некоторые переменные.
Пока, используя
command || return
линии, в сценарии, делает именно то, что я хочу
set -o errexit
делать ... Но я хочу, чтобы это было сделано для всего сценария; не только одна строка / команда
У меня есть файл, полный команд для настройки сайта, и я бы предпочел не делать команду || возвращение
для каждой строки в файле
Есть ли другая опция set или что-то еще, что будет просто «возвращаться» вместо выхода из терминала?
- Просто для ясности , я хотел бы убить скрипт и оставить терминал в том же состоянии, в котором нажатие Ctrl + C для уничтожения службы, запущенной в терминале. command || return
делает это Но я не хочу касаться || return
каждой строки в файле. Поэтому я ищу что-то похожее set -o errexit
, что не приводит к закрытию терминала
--- Примечание: создание тупого скрипта с двумя строками (super.sh):
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
И поместив set -o errexit
в начало create.sh,
работает именно так, как я этого ожидаю. Однако действительно глупо создавать файл с двумя строками, просто для вызова другого скрипта bash, вместо того, чтобы просто вызывать его из терминала. Ugghhh
вот несколько примеров:
в супер.ш
#!/bin/bash
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
в create.sh
#!/bin/bash
set -o errexit
#line below this is a line that fails and will cause the script to stop and return to the terminal as expected
sed "s/@@SITE_NAME@@/$dirname"
~/Desktop/site_builder/template_files/base.html > ~/Desktop/$dirname/templates/base.html # a line with a stupid error
в терминале:
$ bash super.sh
вывод, как ожидалось:
my-mac$
Это работает. Какое досадное решение.
Я хочу , в идеале, выполнить то, что находится в глупом файле super.sh из терминала, а не в файле super.sh: D, без отключения терминала от меня. Вот что происходит с тем, что я пытаюсь сделать:
терминальная команда:
my-mac$ source $create_path blah
в create.sh у меня еще есть set -o errexit
Вот вывод на терминал
sed: 1: "s/@@SITE_NAME@@/blah": unterminated substitute in regular expression
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
А потом терминал заморожен. Ctrl + C не работает, как и Ctrl + D
Если вместо этого set -o errexit
, если я просто использую command || return
операторы везде в файле create.sh, то получаю именно то, что хочу, при выполнении строк в supser.sh непосредственно на терминале (вместо вызова super.sh из терминала). Но это тоже не практическое решение.
Примечание: мне понравился ответ @terdon о создании дочерней оболочки, поэтому я просто создал подпрограмму с помощью сценария, а не терминала, как он показал в своем ответе, используя фигурные скобки ( )
, вокруг всего сценария. Его ответ тоже работает
source $file_path argument
Сценарий выполняется в той же оболочке, из которой я его вызвал (чтоsource
, как мне сказали ... и действует так, как это)command || return
операторы находятся в файле, который я выполняю в терминалеОтветы:
Просто поставьте файл с отказоустойчивым:
... тогда общая команда не потерпит неудачу, даже если это
source
произойдет.источник
source file || true
не делает этого и не делает,source file || return
когда яJills-MBP:~ jillr$ source ~/Desktop/site_builder/create.sh blah || true
он просто выполняет следующую часть скрипта при неудаче, поэтому возвращает вместо true. Единственное, что сработало - этоcommand || return
утверждения в реальном файле для всех команд, что глупо. Я не знаю, если все это добавить в функцию, то вызовfunction || return
в конце файла тоже пойдет на пользу.|| return
команду, которая потерпит неудачу, то да, она вернется. Я думал, что мы пытаемся не допустить выхода вашей основной / родительской оболочки?Это единственное, что работает для того, что мне нужно было выполнить (создать виртуальную среду, затем активировать ее, затем установить требования из скрипта bash):
порождает подоболочку / дочернюю оболочку из скрипта, как в:
stupid_file.sh
запустите stupid_file, используя:
КОНЕЦ.
** берет лук **
(заслуга Джеффа и Тердона)
источник
bash $create_path blah
и посмотреть, завершится ли он, работает ли он так же, и все равно правильно устанавливает вещи в мою виртуальную среду. Вне времени сейчас.(...)
, так как все назначения в скобках влияют только на эту подоболочку.foo=3; (foo=5); echo "$foo"
будет выводить 3, а не 5.source file
с терминала и ожидать таких же результатов. Потому что это никогда не работало. Единственный раз, когда я получаю те же результаты, это когда я создаю вложенную оболочку явно, либо через терминал, либо из сценария. Однако я могу использоватьbash
вместо того,source
чтобы выполнить сценарий, и получить те же результаты, но только когда я явно выполняю свой сценарий в вспомогательной оболочкеpip install -r $apath/requirements.txt
в этой активированной среде. Вот почему я использовал источник в первую очередь для вызова скриптаВ качестве простого обходного пути вы можете запустить оболочку в вашей текущей оболочке и получить исходный код. Что-то вроде:
Откройте новый терминал и настройте все так, как вы хотите. Вы упомянули некоторые переменные среды и тому подобное. Установите их здесь.
В этом терминале запустите новую оболочку. Так , например,
bash
.Занимайся своим делом. Источник вашего сценария. Если он выходит, вы просто выбрасываетесь в первую оболочку, и все еще настроено. Просто беги
bash
снова и ты снова в деле.Чтобы проиллюстрировать это, я создал этот скрипт, который потерпит неудачу, если вы попытаетесь его получить:
Давайте посмотрим, что произойдет, если я начну сеанс вложенной оболочки и затем получу его исходный код (обратите внимание, что я использую переносимое имя для
source
команды.
;source
это bashism):Как вы можете видеть, синтаксическая ошибка вызвала выход исходного сценария, что, в свою очередь, привело к завершению сеанса моей оболочки, но поскольку это был вложенный сеанс, он просто вернул меня к исходной родительской оболочке со всеми установленными переменными , Теперь просто запустите новую оболочку еще раз, и вы можете вернуться к поиску сценария.
источник
create_path=~/Desktop/site_builder/create.sh
в родительской оболочке, потому что я делаю это так часто. И мне нужно вызвать source $ create_path [аргумент] для выполнения скрипта.export
их не используете. Но то, что вы описываете, действительно имеет мало смысла. Это звучит все больше и больше как проблема XY . Возможно, вы захотите опубликовать новый вопрос, объясняющий, какова ваша конечная цель. Могу поспорить, что мы можем дать вам лучшее решение, чем все эти странные источники.