Можно ли выполнять некоторые команды в подпрограмме без немедленного выхода из нее?

Это - конфигурационный файл, таким образом, он подходит удобно к памяти. Нет никакой потребности обработать его как поток.

newline='
' tab=$(echo | tr '\n' '\t')
old=$(cat foo.config)
footer=${old##*"$newline[!$newline$tab #]"}
if [ "$footer" = "$old" ]; then
  footer=
else
  footer=${footer#*"$newline"}
fi
head=${old%"$footer"}
echo "$head$text_to_insert$footer" >foo.config.new
5
19.05.2015, 19:01
3 ответа

Для конкретной проблемы наличия скриптов на POSIX-совместимом языке оболочки, которые устанавливают переменные среды и желают использовать их в fish, существует одно из существующих решений Bass . Это сценарий, который работает аналогично ответу Тердона , но может обрабатывать больше угловых случаев.

1
27.01.2020, 20:38

Для меня (Debian sid/stretch) атрибут udev $ id пуст при подключении устройства USB. Именно $ kernel содержит необходимые последовательности для передачи в unbind USBHID.

Вот правила udev, которые я использую:

SUBSYSTEM=="usb", ATTRS{idVendor}=="0000", ATTRS{idProduct}=="0000", MODE="0660", GROUP="plugdev"
ATTRS{idVendor}=="0000", ATTRS{idProduct}=="0000", DRIVER="usbhid", RUN="/bin/sh -c 'echo -n $kernel >/sys/bus/usb/drivers/usbhid/unbind'"

Замените idVendor и idProduct идентификаторами вашего устройства, конечно.


Для записи этих типов правил следующая команда покажет все атрибуты, которые можно использовать (для данного USB-устройства):

udevadm info -a /sys/bus/usb/devices/1-3:1.0/

Наконец, $ id и $ kernel не являются переменными оболочки; они заменены синтаксическим анализатором udev. Для получения полного списка этих переменных man udev и поиска % k .

-121--45710-

Какая файловая система у вас здесь? Не удалось ли подключить файловую систему только для чтения

Попробуйте изменить

\HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\

на более высокое значение (для тайм-аутов)

-121--76886-

Лично я бы пошел на другой подход. Предположительно, файл нужен в формате борн-типа по другим причинам. Почему бы просто не получить его в рыбе, изменив формат на лету? Что-то вроде:

source (sed -nr 's/(.+)=(.+)/set \1 \2/p' file | psub)

Выше приведен рыбный эквивалент

source <(sed -nr 's/(.+)=(.+)/set \1 \2/p' file)

Например:

> cat file
foo="baz"
export foo
> source (sed -nr 's/(.+)=(.+)/set \1 \2/p' | psub)
> echo $foo
baz

ПРИМЕЧАНИЕ: Это предполагает, что исходный сценарий устанавливает только переменные, как описано в вопросе, и одно определение переменной на строку. Для более сложных операций такой подход не работает.

1
27.01.2020, 20:38

Проблема заключается в том, как вы вызываете специальную встроенную функцию . :

exec /bin/sh -c '. vars.sh; /usr/bin/fish'

В sh , если аргумент не содержит / , . ищет файл в $ PATH . Таким образом, выше он будет искать ] vars.sh в $ PATH вместо текущего каталога, как вы предполагали.

Кроме того, . является специальной встроенной , ее ошибка заставляет оболочку e xit (в не интерактивном режиме), поэтому следующая команда (здесь fish ) не выполняется, поэтому окно эмулятора терминала закрывается без приглашения fish .

Этого можно избежать, позвонив по номеру . как команда . , который удаляет специальный атрибут из специальных встроенных функций.

Обратите внимание, что поведение bash (реализация sh проекта GNU) отличается в этом отношении, когда он не находится в режиме POSIX (когда не вызывается как sh , ни с - posix , ни когда среда не содержит POSIXLY_CORRECT = или SHELLOPTS = posix ):

bash . не вызывает завершение работы оболочки в случае ошибки, и она ищет аргумент без косой черты в текущем каталоге, если не может найти его в $ PATH .

В любом случае, в режиме POSIX или нет, если вам нужен vars.sh в текущем каталоге, вам понадобится синтаксис ./ vars.sh . Итак, это

exec sh -c 'command . ./vars.sh; exec fish'
4
27.01.2020, 20:38

Теги

Похожие вопросы