Чи можливо використовувати змінні параметрів оболонки ($ 1,…, $ @) безпосередньо в CLI?


9

Іноді доводиться емулювати та перевіряти вищезазначені змінні в невеликих прикладах, а потім можна негайно скопіювати у якийсь сценарій тощо.

Я намагався вирішити, використовуючи простий приклад, такими способами:

(find $1) /tmp
sh -c '(find $1) /tmp'
sh -c "find $1" /tmp
echo '(find $1) /tmp' | sh

та з іншими комбінаціями. Також експериментував, додаючи директиву інтерпретатора shebang #!/bin/sh -x, але не отримав бажаного результату.

Чи можу я це зробити просто?


1
(find $1) /tmp- синтаксична помилка. Насправді (any-command) more-argumentsце синтаксична помилка. Чи можете ви пояснити по-різному, що ви намагаєтесь зробити?
Селада

2
@Celada, це не помилка синтаксису в оболонках rcсім'ї ( rc, es, akanga...), де в цьому випадку це еквівалентно find $1 /tmp.
Стефан Шазелас

Відповіді:


15

Перший аргумент після того, як sh -c inline-scriptйде до $0(який також використовується для повідомлень про помилки), а інші йдуть в $1, $2...

$ sh -c 'blah; echo "$0"; echo "$1"' my-inline-script arg
my-inline-script: blah: command not found
my-inline-script
arg

Отже, ви хочете:

sh -c 'find "$1"' sh /tmp

(за старих часів ви могли знайти shреалізації, куди $1замість цього ввійшов перший аргумент , так що ви зробите:

sh -c 'find "$1"' /tmp /tmp

Або:

sh -c 'shift "$2"; find "$@"' sh 3 2 /tmp1 /tmp2

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


Якщо ви хочете встановити $1, $2в локальній області в межах поточної оболонки, що, де ви будете використовувати функції. У Bourne-подібних снарядів:

my_func() {
  find "$1"
}
my_func /tmp

Деякі оболонки підтримують анонімні функції. Ось так zsh:

(){find "$1"} /tmp

Або es:

@{find $1} /tmp

Щоб змінити поточні позиційні параметри, синтаксис постійно залежить від оболонки. dchirikov вже покрив Bourne-подібних оболонках (Bourne, Korn, bash, zsh, POSIX, ash, yash...).

Синтаксис:

set arg1 arg2 ... argn

Однак вам потрібно:

set --

Щоб виповнити цей список (або shift "$#") та

set -- -foo

встановити $1щось, що починається з -або +, тому корисно завжди використовувати, set --особливо коли довільні дані, такі як set -- "$@" other-argдодавання аргументів до кінця списку позиційних параметрів.

У оболонках cshсімейства ( csh, tcsh) ви призначаєте argvмасиву:

set argv=(arg1 arg2)

В оболонках rcсім'ї ( rc, es, akanga), в *масиві:

*=(arg1 arg2)

Хоча ви також можете призначити елементи окремо:

2=arg2

У fishпозиційні параметри в argvмасиві тільки (немає $1, $@є):

set argv arg1 arg2

Для zshсумісності з масивом cshви також можете призначити argvмасив:

argv=(arg1 arg2)
argv[4]=arg4

І ви також можете зробити:

5=arg5

Це означає, що ви також можете робити такі речі, як:

argv+=(another-arg)

додати аргумент до кінця та:

argv[-1]=()
argv[2]=()

щоб видалити аргумент з кінця або середини, що ви не можете легко зробити з іншими оболонками.


7
set --

це те, що вам потрібно:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.