Как @Steven говорит D, не забывайте info
страницы.
Кроме того, не запугивайтесь info
страницы. Я знаю много людей, которые не используют информационные страницы из-за встроенной системы навигации. Мое любимое решение состоит в том, чтобы передать информацию по каналу, пролистывает less
:
info gpg |less
Таким образом, я могу перейти info
страницы с помощью моего любимого пейджера. info
страницы будут теперь вести себя то же как man
страницы.
Вы не можете, портативно, поместить больше чем один аргумент на a #!
строка. Это означает только полный путь и один аргумент (например. #!/bin/sed -f
или #!/usr/bin/sed -f
), или #!/usr/bin/env
и никакой аргумент интерпретатору.
Обходное решение для получения портативного сценария должно использовать #!/bin/sh
и обертка оболочки, передавая sed сценарий как параметр командной строки. Обратите внимание, что это не санкционировано POSIX (сценарии мультиинструкции должны быть записаны с отдельным -e
аргумент в пользу каждой инструкции для мобильности), но это работает со многими реализациями.
#!/bin/sh
exec sed '
s/a/b/
' "$@"
Для длинного сценария может быть более удобно использовать heredoc. Преимущество heredoc состоит в том, что Вы не должны заключать одинарные кавычки в кавычки внутри, если таковые имеются. Главная оборотная сторона - то, что сценарий питается к sed на его стандартном входе с двумя раздражающими последствиями. Некоторые версии sed требуют -f /dev/stdin
вместо -f -
, который является проблемой для мобильности. Хуже, сценарий не может действовать как фильтр, потому что стандартный вход является сценарием и не может быть данными.
#!/bin/sh
exec sed -f - -- "$@" <<'EOF'
s/a/b/
EOF
Оборотная сторона heredoc может быть исправлена полезным использованием cat
. Так как это помещает целый сценарий на командную строку снова, это не совместимо POSIX, но в основном портативно на практике.
#!/bin/sh
exec sed "$(cat <<'EOF')" -- "$@"
s/a/b/
EOF
Другое обходное решение должно записать сценарий, который может быть проанализирован и sh и sed. Это портативно, довольно эффективно, просто немного ужасно.
#! /bin/sh
b ()
{
x
}
i\
f true; then exec sed -f "$0" "$@"; fi
: ()
# sed script starts here
s/a/b/
Объяснения:
b
; содержание не имеет значения, пока функция синтаксически правильно построена (в частности, у Вас не может быть пустой функции). Затем, если верный (т.е. всегда), выполниться sed
на сценарии.()
маркировка, затем некоторый правильно построенный вход. Затем i
команда, которая не имеет никакого эффекта, потому что она всегда пропускается. Наконец ()
маркировка, сопровождаемая полезной частью сценария.Существуют различные несовместимые реализации хижины (#!) в зависимости от ОС. Некоторые создают полный список аргументов, некоторые сохраняют путь команды и помещают все остающиеся аргументы как единственный, некоторые игнорируют все аргументы и передают только путь команды, и наконец, некоторые передают целую строку как единственную команду. Вы, кажется, находитесь в последнем случае.
ENV пытается найти файл с именем "sed-f". Можно попробовать "#!/usr/bin/sed-f" как строка хижины.
Esta respuesta proporciona un camino hacia una solución elegante:https://stackoverflow.com/a/1655389/642372
read
un heredoc en una variable de shell. sed
. Muestra:
#!/usr/bin/env bash
read -rd '' SED_SCRIPT <<EOD
# Your sed script goes here.
s/a/b/
EOD
exec sed "$SED_SCRIPT" "$@"
Мне нравится решение Уокера, но его можно улучшить (, поместив его в отдельный ответ, потому что комментарии не принимают предварительно отформатированный текст ). Это может работать не во всех версиях Linux или Bash, но в Ubuntu 17.10 вы можете сократить это до следующего:
#!/usr/bin/env bash
read SED_SCRIPT <<EOD
s/a/b/
EOD
sed "$SED_SCRIPT" "$@"
Вы можете удалить eval
и упростить команду read
, но вы должны избавиться от комментариев внутри heredoc.
Кроме того, для всего, что вы когда-либо хотели знать о sed, но боялись спросить, есть очень полезный туториал по адресуhttp://www.grymoire.com/unix/sed.html. Это предлагает еще лучшее решение за счет потери /usr/bin/env
и жесткого -кодирования пути к sed :
#!/bin/sed -f
s/a/b/
s/c/d/
Это имеет дополнительное преимущество, заключающееся в поддержке более одной s///
замены.
Начиная с GNU coreutils v8.30 , вы можете сделать:
#!/usr/bin/env -S sed -f
Эта функция была добавлена в недавней (2018 -04 -20)фиксации в env.c
в Пакет GNU coreutils, который добавил опцию -S
или --split-string
.
Из справочной страницы env
:
OPTIONS
-S/--split-string usage in scripts
The -S option allows specifing multiple parameters in a script.
Running a script named 1.pl containing the following first line:
#!/usr/bin/env -S perl -w -T
Will execute perl -w -T 1.pl.
Without the '-S' parameter the script will likely fail with:
/usr/bin/env: 'perl -w -T': No such file or directory
See the full documentation for more details.
Дополнительные примеры доступны в руководстве GNU coreutils .
Если вы также используете опцию -v
для подробного вывода, вы можете увидеть, как именно env
разбивает строку аргументов:
Вmy_sed_script.sed
:
#!/usr/bin/env -vS sed -f
s/a/b/
Исполнение:
$./my_sed_script.sed
split -S: ‘sed -f’
into: ‘sed’
& ‘-f’
executing: sed
arg[0]= ‘sed’
arg[1]= ‘-f’
arg[2]= ‘./my_sed_script.sed’
Примечание.:Это относится только к шебангам, которые используют /usr/bin/env
, т.к. --split-string
является особенностью GNU env
.
#!/usr/bin/env
и никакой аргумент". не формулируется очень хорошо. Возможно, "или#!/usr/bin/env sed
и никакой аргумент sed". – cjm 13.06.2011, 12:03