Считайте (из стандартного файла или файла) произвольную строку в bash и используйте ее без каких-либо расширений оболочки

У меня есть несколько скриптов bash, которые читают произвольные строки (обычно из stdin). Когда эти строки содержат вещи, которые распознает bash, они ломаются.

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

Если я дам ему такие вещи, как

al that didn't work

или же

al I tried a & B

он ломается, потому что bash видит кавычку или амперсанд (или другой метасимвол) и пытается обработать его еще до того, как он попадет в мой сценарий.

Я хотел бы иметь способ принять строку и пропустить ее через фильтр, чтобы избавиться или добавить escape-символы ("\") ко всем символам, которые могут вызвать проблемы, прежде чем я передам строку остальной части моего сценария.

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

Я знаю, что могу просто вводить строки вручную с экранированными символами, но я обычно забываю это делать, и иногда они все равно удаляются позже.

al I tried a \& b
al It didn\'t work

Есть какая-то утилита или способ сделать это без написания с нуля?

1 ответ

Решение

Вы пытаетесь указать произвольную строку в командной строке или как ввод (через stdin) после запуска сценария? Если вы пытаетесь предоставить это в командной строке, вы не можете делать то, что вы пытаетесь (в скрипте, программе на C, что угодно), потому что оболочка всегда анализирует командную строку по своим собственным правилам, прежде чем ваша программа даже запустится.

Если вы пытаетесь прочитать его как ввод после запуска скрипта, это довольно легко сделать с помощью read Команда, хотя есть несколько хитростей, чтобы получить правильно "сырой" ввод. Используйте что-то вроде:

IFS= read -r -p "Enter the string: " str

IFS= часть препятствует тому, чтобы это урезало пробел; -r мешает ему интерпретировать побеги. -p "Enter the string: " это необязательная тонкость, не стесняйтесь оставить ее, если это уместно.

(Кстати, так как IFS= используется в качестве префикса к read команда, она применяется только к этой одной команде и не должна быть впоследствии возвращена к нормальной.)

Обратите внимание, что при использовании переменной (str в этом случае), вы всегда должны заключать его в двойные кавычки (например, echo "$str") чтобы оболочка не выполняла разбор содержимого на этом этапе. На самом деле, вы все равно должны почти всегда заключать двойные кавычки в переменные оболочки - количество вопросов о скриптах оболочки, которые мы получаем здесь, где решение "двойные кавычки ваших переменных" довольно страшно.

Другие вопросы по тегам