Оценка
Эти работы:
$ echo hi
hi
$ eval "echo hi"
hi
$ exec echo hi
hi
Однако это не:
$ exec "echo hi"
bash: exec: echo hi: not found
$ "echo hi"
bash: echo hi: command not found
Замена образа процесса
Этот пример демонстрирует, как exec
заменяет образ своего вызывающего процесса:
# Get PID of current shell
sh$ echo $$
1234
# Enter a subshell with PID 5678
sh$ sh
# Check PID of subshell
sh-subshell$ echo $$
5678
# Run exec
sh-subshell$ exec echo $$
5678
# We are back in our original shell!
sh$ echo $$
1234
Обратите внимание, что exec echo $$
выполняется с PID подоболочки! Кроме того, после того, как он был завершен, мы вернулись в нашу исходную sh$
оболочку.
С другой стороны, eval
не не заменяет образ процесса. Скорее, он запускает данную команду, как обычно в самой оболочке. (Конечно, если вы запускаете команду, которая требует запуска процесса... она делает именно это!)
sh$ echo $$
1234
sh$ sh
sh-subshell$ echo $$
5678
sh-subshell$ eval echo $$
5678
# We are still in the subshell!
sh-subshell$ echo $$
5678
Я предполагаю, что вы на самом деле используете двойные кавычки вокруг выражения sed
, а не одинарные кавычки, иначе вы не получили бы эту ошибку.
Я также предполагаю, что вы используете в своем значении $replace
строку, содержащую косую черту(/
). Когда переменная расширяется, ее значение вставляется в инструкцию sed
, и поскольку оно содержит косую черту, это нарушает синтаксис команды s///
.
Вы можете решить эту проблему, изменив разделитель, который вы используете в команде sed
, на другой символ, которого нет в $replace
.
Если выбрать @
, например,
sed -i -e 's@\(dataTable\)@'"$replace"' \1@' file.txt
Обратите внимание, что у вас все еще будет проблема, если ваша строка $replace
содержит подстроки \x
(, где x
— любая цифра )или &
(, которая будет заменена частью строки, которая соответствует выражение ). Вам придется избежать этих специальных строк.
См., например,.
В качестве особого случая, если вы планируете заменить целую строку новым (статическим )содержимым, вы можете сделать это следующим образом:
printf '%s\n' "$replace" | sed -e '/some pattern/{ r /dev/stdin' -e 'd; }' file.txt
Это находит строку, соответствующую /some pattern/
, а затем считывает текст замены из стандартного ввода (из printf
). Затем он удаляет старую строку.