Передача переменной в скрипт bash, который использует 'EOF' и считает переменную литералом [закрыто]

9

в этом сценарии я получаю «$ 1», сохраняемый в файл / test.

#!/bin/bash
cat > /test << 'EOF'
$1
EOF

правда в том .. мне нужно сохранить

'EOF'

как 'EOF', потому что мой аргумент ($ 1) содержит знаки доллара.

но мне нужно сохранить этот аргумент, а не 1 доллар

user72685
источник
1
'потому что мой аргумент ( $1) содержит знаки доллара.' Нет, если это относится к первому параметру командной строки. Замена была выполнена до того, как ваш скрипт был выполнен. Вы должны избежать этого в командной строке.
Златовласка
Вы задали несколько связанных вопросов об этой задаче, и последовательность вопросов показывает, что вы на самом деле не понимаете, что происходит, и, вероятно, не выбираете самый простой подход. Трудно помочь вам, не зная, что вы пытаетесь сделать, поэтому я рекомендую вам задать вопрос, в котором вы четко объясните свою общую задачу и не ограничиваете ответы использованием определенного инструмента. Например, не говорите «Я хочу использовать catи сохраняйте знаки доллара», но «я хочу изменить параметр, httpd.confчтобы изменить <некоторые настройки> в <этот способ>».
Жиль "ТАК - перестань быть злым"
@ Жиль, в конце концов я решил написать в другой файл через python, а затем использовать скрипт bash, чтобы записать этот файл в исходный файл, который был отредактирован. этот процесс намного проще. cat / temp_file> $ 1
user72685
@ Жиль, причина, по которой мои вопросы не имеют смысла, заключается в том, что сценарии bash обрабатывают переменные, передаваемые им. Есть слишком много вещей, которые нужно экранировать, и все же нет возможности кодировать и декодировать на лету.
user72685
@Gilles, единственная вещь, которая имела смысл для меня, была base64, но почему нужно кодировать их вещи, чтобы перейти к скрипту bash ... экранировать вещи, а затем пытаться воссоздать вещи внутри скрипта bash .. целых три косых черты, чтобы избежать обратного удара и т. д. мне кажется, что это адский код
user72685

Ответы:

15

Вслед за ваш предыдущий вопрос , это звучит , как вы хотите , и некоторые неосмысленный текст и некоторые интерпретировать текст происходят в файл. В этом случае используйте два разных cats (или echos):

cat > /test <<'EOF'
some uninterpreted text $(pwd)
not substituted: $1
EOF
cat >> /test <<EOF
but this will substitute: $1
EOF

Здесь происходит пара вещей: во-первых, синтаксис heredoc с <<. Если вы включите кавычки в эту строку терминатора, как в первом примере выше, весь heredoc не интерпретируется - без параметров и без подстановок. Если вы не используете кавычки, как во втором cat выше, переменные наподобие $1будут заменены их значениями, а подстановки команд будут включены в текст. Вы выбираете, заключить в кавычки строку «EOF» или нет, основываясь на том, хотите ли вы замены или нет.

Чтобы поместить оба catфайла в один и тот же файл, мы используем >> перенаправление для второго (и любого более позднего) перенаправления: это означает добавление в файл. Для первого мы используем один, >чтобы очистить файл и начать все заново.

Обратите внимание, что даже при замене переменных любые дополнительные знаки доллара в значении этой переменной сами по себе не заменяются:

foo='$bar'
bar=hello
cat <<EOF
$foo
EOF

будет выводить:

$bar

без подстановки в $barзначение.

Однако, если вы указываете «$» в качестве аргумента для всего этого сценария, вам нужно экранировать его в командной строке или заключить все это в одинарные кавычки. В качестве альтернативы, подстановка команд, как и в вашем другом вопросе, позволяет вам поместить содержимое всего файла напрямую, включая любые знаки доллара в содержимом файла. Убедитесь, что вы указали там строку подстановки:

oo.sh "$(cat myfile)"

получит тело myfileкак $1и может тогда catили echoэто как требуется. Здесь применимы те же ограничения, что и в моем ответе : есть ограничение на длину аргументов командной строки, и если ваш файл может стать длиннее, вы должны найти другой подход. Вы можете узнать, какой лимит в вашей системе сgetconf ARG_MAX

Майкл Гомер
источник
1

Похоже, вы просто хотите вывести одну переменную в файл. В этом случае это будет работать:

echo $1 >/test

Обратите внимание, что он /testнаходится в корневом каталоге, для которого обычные пользователи обычно не имеют разрешения на запись.

РЕДАКТИРОВАТЬ: Имейте в виду, что вам нужно заключить в кавычки строку, содержащую знак доллара, в командной строке . Вот где происходит подмена, и сценарий ничего не может с этим поделать.

Том Зыч
источник
Я думаю, что у вас есть правильный ответ сейчас. +1
Златовласка
Ответ @ MichaelHomer гораздо более полный и содержит полезную информацию о документах, о которых я забыл. Его ответ должен быть принят (если, конечно, кто-то еще не опубликовал еще лучший).
Том Зыч