Ви неправильно трактуєте сторінку чоловіка. По-перше, частина про --
сигналізацію про закінчення параметрів не має значення для того, що ви намагаєтесь зробити. З цього -c
моменту переорієнтовує решту командного рядка, так що він більше не проходить через керування опціями bash, це означає, що --
перехід буде переданий команді, а не обробляється bash як кінець маркера параметрів.
Друга помилка полягає в тому, що додаткові аргументи призначаються як позиційні параметри запущеного процесу оболонки, а не передаються як аргументи команді. Отже, те, що ви намагаєтесь зробити, можна зробити як один із:
/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar
У першому випадку, передаючи параметри ехо $0
і $1
явно, а в другому випадку, використовуючи "$@"
для розширення настільки ж нормально, як "всі позиційні параметри, крім $ 0". Зауважте, що і в цьому випадку ми повинні передавати те, що також буде використано $0
; Я вибрав "баш", оскільки це $0
зазвичай було б, але все інше спрацювало б.
Що стосується причини, яка робиться таким чином, замість того, щоб просто передавати будь-які аргументи, які ви даєте безпосередньо команді, яку ви перераховуєте: зауважте, що в документації написано "команда s читається з рядка", множина. Іншими словами, ця схема дозволяє робити:
/bin/bash -c 'mkdir "$1"; cd "$1"; touch "$2"' bash dir file
Але зауважте, що кращим способом досягнення первинної мети може бути використання, env
а не bash
:
/usr/bin/env -- "ls" "-l"
Якщо вам не потрібна якась функція, яку надає оболонка, немає ніяких причин використовувати її - використання env
в цьому випадку буде швидшим, простішим та меншим набором тексту. І вам не потрібно думати так важко, щоб переконатися, що він буде безпечно обробляти імена файлів, що містять метахарактеристики оболонки або пробіли.