Это - конфигурационный файл, таким образом, он подходит удобно к памяти. Нет никакой потребности обработать его как поток.
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
Для конкретной проблемы наличия скриптов на POSIX-совместимом языке оболочки, которые устанавливают переменные среды и желают использовать их в fish, существует одно из существующих решений Bass . Это сценарий, который работает аналогично ответу Тердона , но может обрабатывать больше угловых случаев.
Для меня (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
.
Какая файловая система у вас здесь? Не удалось ли подключить файловую систему только для чтения
Попробуйте изменить
\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
ПРИМЕЧАНИЕ: Это предполагает, что исходный сценарий устанавливает только переменные, как описано в вопросе, и одно определение переменной на строку. Для более сложных операций такой подход не работает.
Проблема заключается в том, как вы вызываете специальную встроенную функцию .
:
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'