Как правильно выйти из этой длинной команды su + sed?

echo '0A' производит три символа: NL на 0 А; xxd -b затем распечатает те три символа в двоичном файле. Если Вы хотели просто единственный байт, значение которого равняется 10 (т.е. шестнадцатеричный A), Вы могли записать (в ударе):

echo -n $'\x0A'
      ^ ^  ^
      | |  |
      | |  +-- `\x` indicates a hexadecimal escape
      | +----- Inside a $' string, escapes are interpreted
      +------- -n suppresses the trailing newline

Лучшая альтернатива была бы printf '\x0A'; printf интерпретирует escape-последовательности в строке формата и не производит неявные новые строки. (Это - Posix-совместимое решение, которое должно работать над любой Posix-совместимой оболочкой.) Еще одна возможность удара echo -n -e '\x0A'; (нестандартный) -e флаг просит отзываться эхом для интерпретации escape-последовательностей.

Я понятия не имею, почему Вы ожидали бы echo '1' | xxd -b производить эквивалент шестнадцатеричного числа 50. Как Вы ожидаете xxd понять это 0A шестнадцатеричное число и 1 не? Кроме того, почему 50? (Код ASCII для символа 1 шестнадцатеричное число 31.)

Порядок байтов не влияет на байты. Порядок битов в байте совершенно концептуален, пока байт не передается по последовательной линии, и даже затем это только видимо с осциллографом или чем-то подобным.

2
21.05.2015, 01:12
1 ответ

Theory

Theory

The rules are :

  • внутри делимитированной строки ' ничего не интерпретируется и ничего, кроме ', не имеет особого значения. Это означает, что только ' нужно экранирование, но это также означает, что для того, чтобы экранироваться, нужна конструкция '\'. (Первая ' заканчивается строкой, следующая \' добавляет литерал ' (escap предотвращает начало новой строки), а последняя ' начинает новую строку. так как эти три строки не разделены разделителем (обычно пробелом), они будут рассматриваться как одна сплошная строка.

  • Внутри строки " происходит расширение переменных и интерпретация экранировок. Поэтому, если вам нужен литерал \, вам нужно будет экранироваться от него. Также, если вам нужен литерал $, вам также нужно экранироваться (иначе он будет интерпретирован как расширение переменной).

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

Также помните, что sed также интерпретирует \ как экранирующий символ, что означает, что вам также необходимо экранировать этот символ, когда вы используете его буквально внутри скрипта sed.

Пример

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

Например, если вы хотите заменить строку Это тест на Это мой тест в файле /home/user/I имеют пробелы в моем имени.txt и поместить результат в файл /home/user/NoSpaces. txt, вы могли бы использовать " кавычки вокруг него, чтобы сделать это проще, например :

sed "s/It's a test/It's my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt

Теперь, если вы хотите сохранить это внутри переменной, вам нужно будет добавить другой уровень кавычек.

  • Вы можете сделать это, используя ' (что означает только необходимость escape других ' символов в вашей текущей строке):

    myvar='sed "s/It'\''s a test/It'\''s my test/" "/home/user/I have пробелы в моем имени.txt" >/home/user/NoSpaces.txt"

    myvar='sed "s/It'\''s a test/" "/home/user/I have пробелы в моем имени.txt" >/home/user/NoSpaces.txt'.
    
  • Вы также можете сделать это, используя кавычки в стиле ":

    myvar="sed \'s/It's a test/It's my test/\". \ "/home/user/I есть места на мое имя.txt\". >/home/user/NoSpaces.txt".
    

Правило заключается в том, чтобы всегда идти с тем решением, которое кажется тебе самым чистым.

Решение

Учитывая это, для вашей конкретной проблемы вы можете попробовать следующее :

cmd="sed -i '\$ialias ptgui '\\''wine ~/.wine/drive_c/Program\\\\ Files/PTGui/PTGui.exe'\\' /usr/people/$wineuser/config/cshrc.csh"
su "$wineuser" -c "$cmd"

Обратите внимание, что я бы предложил использовать append вместо insert команды для sed, но это выходит за рамки вопроса.

4
27.01.2020, 22:00

Теги

Похожие вопросы