Обратная косая черта внутри псевдонима, который не сохраняется как часть его определения

#linux #bash #ubuntu #zsh #alias

Вопрос:

У меня есть сеансы экрана с именем BedrockServer. Я ввел псевдоним вот так:

 alias stop='screen -R BedrockServer -X stuff "stop $(printf 'r')"'
 

Но когда я печатаю alias , в нем указывается, что

 alias stop='screen -R BedrockServer -X stuff "stop $(printf r)"'
 

и псевдоним не работает.


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

Есть идеи, что я делаю не так?

Комментарии:

1. Использование функции вместо псевдонима позволит избежать проблем здесь.

2. Тем не менее, какова цель этого $(printf 'r') ? Гораздо эффективнее создавать строку $'stop r' без подстановки команд. (Командные замены порождают подоболочки; порождение подоболочки-одна из самых медленных вещей, которые оболочка может выполнить без execve() системного вызова семейства).

3. $'...' является строковым синтаксисом, подобным ANSI C. Это не предусмотрено POSIX, но и bash, и zsh предоставляют его.

4. Все вышесказанное говорит о том, что я бы написал это так stop() { screen -R BedrockServer -X stuff $'stop r'; } . Псевдонимы являются неправильными-если бы оболочка была переработана с нуля сегодня без ограничений обратной совместимости, они, вероятно, вообще не существовали бы.

5. Вся проблема может быть упрощена до echo r «или xxd <<<r «, что показывает, что r это просто равно r . ОТО, xxd <<<\r покажет вам, что \r это действительно обрабатывается как одна обратная косая черта, за которой следует буква r .

Ответ №1:

Внутри одинарных кавычек все символы, кроме ' теряют свое особое значение. Поэтому $( ) пока не интерпретируется. Если бы это было интерпретировано, вы могли бы вставить кавычки. Но поскольку он не интерпретируется, вы не можете вставлять кавычки.

Ваш псевдоним в основном

 'some literal string 'anUnquotedString' another literal string'
 

Строка без кавычек r такая же, как r .

Использование функции вместо псевдонима легко решает проблемы с цитированием.

 stop() {
  screen -R BedrockServer -X stuff "stop $(printf 'r')"
}
 

Если вы хотите придерживаться псевдонима, существует множество вариантов правильного цитирования, например

 alias stop="screen -R BedrockServer -X stuff "stop $(printf '\r')""
 

Обе команды сверху выполняются printf при каждом выполнении stop . В этом нет необходимости. В псевдониме вы можете выполнить его один раз для определения (обратите внимание на пропущенное ранее $( ) ).:

 alias stop="screen -R BedrockServer -X stuff "stop $(printf 'r')""
 

А для функции и/или псевдонима вы даже можете printf полностью отказаться, используя строку ANSI C:

 stop() {
  screen -R BedrockServer -X stuff 


Комментарии:

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

stop r'
}
alias stop=

Комментарии:

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

screen -R BedrockServer -X stuff "stop r"'

Комментарии:

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