Чому не systemctl \ {перезапуск, статус} \ sshd \; робота?


14

Вихід з вищевказаної команди при передачі через ехо:

# echo systemctl\ {restart,status}\ sshd\;
systemctl restart sshd; systemctl status sshd;

Навіть якщо я вставити висновок в термінал, команда працює. Але коли я намагаюся безпосередньо запустити команду, я отримую:

# systemctl\ {restart,status}\ sshd\;
bash: systemctl restart sshd;: command not found...

У мене два питання ..

  1. Як саме називається цей спосіб заміщення та розширення? (Щоб я міг дослідити його та дізнатися більше про нього та як правильно ним користуватися).
  2. Що я тут зробив не так? Чому це не працює?

Відповіді:


26

Це форма розширення Brace, виконана в оболонці. Ідея розширення дужок є правильною, але спосіб її використання тут неправильний. Коли ви мали намір зробити:

systemctl\ {restart,status}\ sshd\;

Оболонка інтерпретується systemctl restart sshd;як одна довга команда і намагається запустити її, і вона не змогла знайти бінарний файл, щоб запустити її таким чином. Оскільки на цьому етапі оболонка намагається токенізувати елементи в командному рядку, перш ніж будувати повну команду з аргументами - але це ще не сталося.

Для таких відомих значень розширення ви можете використовувати evalта залишатись безпечними, але будьте впевнені в тому, що намагаєтесь розширити за допомогою нього.

eval systemctl\ {restart,status}\ sshd\;

Але я б скоріше використовував цикл, а не for, а не намагався написати однолінійку або використовувати eval:

for action in restart status; do
    systemctl "$action" sshd
done

19

Це називається розширенням дужок (як вказує тег).

Що я тут зробив не так? Чому це не працює?

Розглянемо етапи, пов’язані з читанням та виконанням командного рядка в bash (наприклад):

  1. читає рядок
  2. розбирає, можливо, складну команду на складові прості команди
  3. робить різні розширення на прості команди (розширення дужок, розбиття слів, глобулювання тощо)
  4. потім виконує прості команди (з іншими етапами, пропущеними для наочності).

Те, що ви намагаєтесь зробити, - це вплинути на (2) від (3). Розбиття на основі ;знаходиться на етапі (2), коли він розбирає складені команди. До моменту, коли (3) відбувається розширення дужок, вже пізно спробувати створити складну команду.


6

Перший рядок

echo systemctl\ {restart,status}\ sshd\;

розгорнути як 3 лексеми

  • відлуння
  • systemctl перезапустити sshd;
  • systemctl статус sshd;

потім повторюються останні два маркери, і це виглядає нормально.

аналогічно другий рядок

systemctl\ {restart,status}\ sshd\;

розширюється як 2 лексеми

  • systemctl перезапустити sshd;
  • systemctl статус sshd;

і bash намагаються шукати виконуваний файл, systemctl restart sshd;який він не міг знайти.

Ви можете хотіти розпочати свою подорож з темної сторони, eval systemctl\ {restart,status}\ sshd\;остерігаючись несподіваного.


тож рішенням було б розділення слів, правда? Як це можна зробити?
Somenath Sinha
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.