Набор текста /usr/bin/env sed -f
в терминале работает.
Но если использовать его как шебанг,
#!/usr/bin/env sed -f
s/a/b/
Сценарий не будет выполнен:
/usr/bin/env: sed -f: No such file or directory
Я верю, что это связано с -f. Но как решить это?
scripting
sed
executable
env
Cheng
источник
источник
Ответы:
Вы не можете, переносимым, поставить более одного аргумента в
#!
строке . Это означает только полный путь и один аргумент (например,#!/bin/sed -f
или#!/usr/bin/sed -f
), или#!/usr/bin/env
нет аргумента интерпретатору.Обходной путь для получения переносимого скрипта - использовать
#!/bin/sh
оболочку оболочки, передавая скрипт sed в качестве аргумента командной строки. Обратите внимание, что это не разрешается POSIX (сценарии с несколькими инструкциями должны быть написаны с отдельным-e
аргументом для каждой инструкции для переносимости), но это работает со многими реализациями.Для длинного сценария может быть удобнее использовать heredoc. Преимущество heredoc в том, что вам не нужно заключать в кавычки одинарные кавычки, если они есть. Основным недостатком является то, что сценарий подается на sed на своем стандартном вводе, с двумя досадными последствиями. Некоторые версии sed требуют
-f /dev/stdin
вместо этого-f -
, что является проблемой для переносимости. Хуже того, скрипт не может выступать в качестве фильтра, потому что стандартным вводом является скрипт и он не может быть данными.Недостаток heredoc может быть исправлен путем полезного использования
cat
. Так как это снова помещает весь сценарий в командную строку, он не POSIX-совместимый, но практически переносимый на практике.Другой обходной путь - написать скрипт, который может быть проанализирован как sh, так и sed. Это портативный, достаточно эффективный, просто немного уродливый.
Пояснения:
b
; содержимое не имеет значения, пока функция синтаксически правильно сформирована (в частности, у вас не может быть пустой функции). Затем, если true (т.е. всегда), выполнитьsed
на сценарии.()
метке, затем некоторый правильно сформированный ввод. Затемi
команда, которая не имеет никакого эффекта, потому что она всегда пропускается. Наконец за()
меткой следует полезная часть скрипта.источник
#!/usr/bin/env
и без аргументов». не очень хорошо сформулировано. Возможно, «или#!/usr/bin/env sed
нет аргументов для сед».Существуют различные несовместимые реализации shebang (#!) В зависимости от ОС. Некоторые создают полный список аргументов, некоторые сохраняют путь команды и помещают все оставшиеся аргументы как один, некоторые игнорируют все аргументы и передают только путь команды, и, наконец, некоторые передают всю строку как одну команда. Вы, кажется, в последнем случае.
источник
env пытается найти файл с именем "sed -f". Вы можете попробовать "#! / Usr / bin / sed -f" в качестве строки shebang.
источник
Начиная с GNU coreutils v8.30 , вы можете делать:
Эта функция была добавлена в недавнем (2018-04-20) совершить , чтобы
env.c
в ГНУ Coreutils пакет, который добавил к-S
или--split-string
вариант.Со
env
страницы руководства :Дополнительные примеры доступны в руководстве по GNU coreutils .
Если вы также используете
-v
опцию для подробного вывода, вы можете увидеть, как именноenv
разбивает строку аргументов:В
my_sed_script.sed
:Исполнение:
Примечание. Это относится только к используемым шебангами
/usr/bin/env
, так как--split-string
это особенность GNUenv
.источник
Этот ответ предоставляет путь к элегантному решению: /programming//a/1655389/642372
read
наследник в переменную оболочки.sed
.Образец:
источник
Мне нравится решение Уокера, но его можно улучшить (поместив его в отдельный ответ, потому что комментарии не принимают предварительно отформатированный текст). Это может не работать на всех версиях Linux или Bash, но в Ubuntu 17.10 вы можете сократить это до следующего:
Вы можете удалить
eval
и упроститьread
команду, но вы должны избавиться от комментария внутри heredoc.Кроме того, для всего, что вы когда-либо хотели знать о sed, но боялись спросить, есть очень полезное руководство по адресу http://www.grymoire.com/unix/sed.html . Это предлагает еще лучшее решение за счет потери
/usr/bin/env
и жесткого кодирования пути к sed:Это имеет дополнительное преимущество поддержки более чем одной
s///
замены.источник