Повторение команды echo с переменной в bash

хорошо, вот один, с которым я борюсь, пока мы говорим. Повторение команды echo с переменной.

echo "creating new script file."
echo "#!/bin/bash" > $servsfile
echo "read -p "Please enter a service: " ser " >> $servfile
echo "servicetest=`getsebool -a | grep ${ser}` " >> $servfile
echo "if [ $servicetest > /dev/null ];then " >> $servfile
echo "echo "we are now going to work with ${ser}" " >> $servfile
echo "else" >> $servfile
echo "exit 1" >> $servfile
echo "fi" >> $servfile

моя цель-создать скрипт с помощью команд echo, а затем запустить его позже. Мне просто нужно выяснить, как эхо-команды echo/read при сохранении моих переменных.

edit: переменные должны передать то, что внутри них, в новый файл.

3 ответов


echo "echo "we are now going to work with ${ser}" " >> $servfile

Escape all " в кавычках с \. Сделайте это с такими переменными, как \$servicetest too:

echo "echo \"we are now going to work with ${ser}\" " >> $servfile    
echo "read -p \"Please enter a service: \" ser " >> $servfile
echo "if [ $servicetest > /dev/null ];then " >> $servfile

непосредственная проблема у вас с цитированием: используя двойные кавычки, ваши ссылки на переменные являются мгновенно расширен, что, вероятно, не то, что вы хотите.

использовать один кавычки вместо этого-строки внутри одинарных кавычек не расширяются или не интерпретируются каким-либо образом оболочкой.

(если вы хотите выборочная расширение внутри строки-т. е. развернуть некоторую переменную ссылки, но не другие-используйте двойные кавычки, но префикс $ ссылок вы не хочу расширить с \, например, $var).

, вам лучше использовать один здесь-doc [ument], который позволяет создать многострочный stdin вход на месте, заключенный в скобки двумя экземплярами self-chosen разделитель, открывающий с префиксом <<, и закрывающий на a линия сама по себе - начиная с самого первого столбца; поиск Here Documents на man bash или в http://www.gnu.org/software/bash/manual/html_node/Redirections.html.

если вы цитата здесь-doc разделитель (EOF в коде ниже), ссылки на переменные также не расширен. Как указывает @chepner в комментарии, Вы можете выбрать метод цитирования в этом случае: enclose разделитель в одинарных кавычках или двойные кавычки или даже просто произвольно избежать одного символа в разделителе с \:

echo "creating new script file."

cat <<'EOF'  > "$servfile"
#!/bin/bash
read -p "Please enter a service: " ser
servicetest=`getsebool -a | grep ${ser}` 
if [ $servicetest > /dev/null ]; then 
  echo "we are now going to work with ${ser}"
else
  exit 1
fi
EOF

как отмечает @Bruce K в комментарии, вы можете префикс здесь-doc разделитель с - (применительно к этому примеру:<<-"EOF") для ведущие вкладки лишен, позволяющ для отступа который делает фактическое содержание здесь-doc более легким к различать. Заметим, однако, что это работает только с фактическими tab символы, а не пробелы.

используя эту технику в сочетании с запоздалыми мыслями относительно содержимого скрипта ниже, мы получаем (опять же, обратите внимание, что фактический tab chars. необходимо использовать, чтобы привести каждую строку содержимого here-doc для их удаления):

cat <<-'EOF' > "$servfile"
    #!/bin/bash
    read -p "Please enter a service name: " ser
    if [[ -n $(getsebool -a | grep "${ser}") ]]; then 
      echo "We are now going to work with ${ser}."
    else
      exit 1
    fi
EOF

наконец, обратите внимание, что в bash даже обычные одинарные или двойные кавычки строки могут охватывать несколько линии, но вы не получите преимущества tab-stripping или линейного блока, как все внутри кавычек становится частью строки.

таким образом, обратите внимание, как в следующем #!/bin/bash должен следовать за открытием ' тут для того, чтобы стать первой строке вывода:

echo '#!/bin/bash
read -p "Please enter a service: " ser
servicetest=$(getsebool -a | grep "${ser}")
if [[ -n $servicetest ]]; then 
  echo "we are now going to work with ${ser}"
else
  exit 1
fi' > "$servfile"

размышления относительно содержания вашего скрипта:

  • синтаксис $(...) предпочтительнее `...` для замены команд в настоящее время.
  • вы должны двойной кавычки ${ser} на grep команда, так как команда, скорее всего, сломается, если значение содержит встроенные пробелы (или убедитесь, что значение read не содержит пробелов или других метасимволов оболочки).
  • использовать [[ -n $servicetest ]] чтобы проверить, является ли $servicetest пусто (или выполните замену команды непосредственно внутри условного) -[[ ... ]] - предпочтительная форма в bash - защищает вас от нарушение условного, если $servicetest случается иметь встроенные пространства; никогда нет необходимости подавлять вывод stdout внутри условного (будь то [ ... ] или [[ ... ]], поскольку выход stdout не передается; таким образом,> /dev/null является избыточным (тем не менее, с заменой команды внутри условного,stderr output пропускается через).

вам просто нужно использовать одинарные кавычки:

$ echo "$TEST"
test
$ echo '$TEST'
$TEST

внутри одинарных кавычек специальные символы больше не являются особенными, они просто обычные символы.