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

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

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

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

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

Ответ 1

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

Escape all "внутри кавычек с \. Делайте это с помощью таких переменных, как \$servicetest:

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

Ответ 2

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

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

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

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

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

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"), чтобы лидировать вкладки разделены, что позволяет для отступов, которые облегчают определение фактического содержания этого документа. Обратите внимание, однако, что это работает только с фактическими символами табуляции, а не с ведущими пробелами.

Используя эту технику в сочетании с запоздалыми мыслями относительно содержимого script ниже, мы получаем (опять же, обратите внимание, что фактические символы табуляции должны использоваться для того, чтобы привести каждую строку содержания-документа для их удаления):

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 даже нормальные строки с одним или двумя кавычками могут охватывать несколько строк, но вы не получите преимуществ от зачистки вкладок или охвата линейного блока, поскольку все внутри кавычек становится частью строки.

Таким образом, обратите внимание на то, что в следующем #!/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"

Последующие мысли о содержании вашего script:

  • Синтаксис $(...) предпочтительнее `...` для замены команд в настоящее время.
  • Вы должны выполнить двойную кавычку ${ser} в команде grep, так как команда, вероятно, сломается, если значение содержит встроенные пространства (в качестве альтернативы убедитесь, что оценочное чтение не содержит пробелов или других метасимволов оболочки).
  • Используйте [[ -n $servicetest ]] для проверки того, является ли $servicetest пустым (или выполнить подстановку команд непосредственно внутри условного выражения) - [[ ... ]] - предпочтительная форма в bash - защищает вас от нарушения условного выражения, если $servicetest имеет встроенные пространства; НИКОГДА не нужно подавлять вывод stdout внутри условного (независимо от того, [ ... ] или [[ ... ]], поскольку не передается выходной сигнал stdout, поэтому > /dev/null является избыточным (это означает, что с заменой команды внутри условного, stderr выход IS прошел).

Ответ 3

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

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

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