Во-первых, поскольку вы работаете на Mac, один вариант -i
не будет работать. Вам нужно указать для него значение, в вашем случае пустое.
Во-вторых, в вашем случае можно изменить пару p;b
на p;d
, так как действует переключатель -n
. Команда ветвления b
плохо сочетается с закрывающими фигурными скобками в более старых версиях seds
.
$ sed -i '' -ne '/# BEGIN AUTO GENERATED CONTENT/{' -e 'p;r config' -e ':a;n' -e '/# END AUTO GENERATED CONTENT/{' -e 'p;d' -e '}' -e 'ba' -e '}' -e 'p' ~/.ssh/config
Если это не использование -и -выбрасывания чего-то подобного, лучше всего переписать его в файл, а затем вызывать как:
$ sed -i '' -nf./code ~/.ssh/config
$ cat./code
/# BEGIN AUTO GENERATED CONTENT/{
p
r config
:loop
n
/# END AUTO GENERATED CONTENT/{
p
d
}
bloop
}
p
Да, &>
— это оператор bash
(, теперь также поддерживаемый zsh
, в то время как zsh
всегда имел >&
для того же, что и в csh
), а >(...)
— ksh
. ] оператор (теперь также поддерживается zsh
и bash
), ни один из них не является оператором sh
. Тот $LOG _FILE без кавычек, где явно не нужен split+glob, делает синтаксис zsh (единственной из тех оболочек, где split+glob не выполняется неявно при расширении без кавычек, хотя в zsh
, вы бы просто сделалиexec >&1 > $LOG_FILE 2>&1
).
В синтаксисе sh
вы можете сделать:
#! /bin/sh -
LOG_FILE="/tmp/abc.log"
{
# your script here
} 2>&1 | tee -- "$LOG_FILE"
Или поместить все в функцию:
#! /bin/sh -
LOG_FILE="/tmp/abc.log"
main() {
# your script here
}
main "$@" 2>&1 | tee -- "$LOG_FILE"
В любом случае, как этот, так и вашzsh
-подход в стиле приведут к печати сообщений об ошибках на том же ресурсе, который открыт на стандартном выводе. Поэтому, если кто-то это сделает, your-script > out 2> err
, err
будет пустым, а out
будет содержать как нормальный вывод, так и ошибки.
Чтобы убедиться, что исходный пункт назначения вывода и ошибки сохранен, вместо этого вы можете сделать:
{
{
main "$@" 3>&- | tee -a -- "$LOG_FILE" >&3 3>&-
} 2>&1 | tee -a -- "$LOG_FILE" >&2 3>&-
} 3> "$LOG_FILE" 3>&1
(не проверено ).