是否可以直接在 CLI 中使用 shell 参数变量 ($1, ..., $@)?

Apo*_*tle 9 shell parameter

有时需要在小例子中模拟和验证上述变量,然后可以立即复制到某些脚本等。

我试图通过以下方式使用一个简单的例子来解决:

(find $1) /tmp
sh -c '(find $1) /tmp'
sh -c "find $1" /tmp
echo '(find $1) /tmp' | sh
Run Code Online (Sandbox Code Playgroud)

以及其他组合。还通过添加 shebang 解释器指令进行了试验#!/bin/sh -x,但没有得到预期的结果。

我可以简单地做到这一点吗?

Sté*_*las 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
Run Code Online (Sandbox Code Playgroud)

所以你要:

sh -c 'find "$1"' sh /tmp
Run Code Online (Sandbox Code Playgroud)

(在过去,你可以找到sh第一个 arg 进入的实现$1,所以你会这样做:

sh -c 'find "$1"' /tmp /tmp
Run Code Online (Sandbox Code Playgroud)

或者:

sh -c 'shift "$2"; find "$@"' sh 3 2 /tmp1 /tmp2
Run Code Online (Sandbox Code Playgroud)

来解释这两种行为,但是现在 POSIX 流行且公开可用,这些 shell 已经消失了)。


如果您想在当前 shell 的本地范围内设置$1,那么您将$2在那里使用函数。在类似 Bourne 的 shell 中:

my_func() {
  find "$1"
}
my_func /tmp
Run Code Online (Sandbox Code Playgroud)

一些 shell 支持匿名函数。情况就是这样zsh

(){find "$1"} /tmp
Run Code Online (Sandbox Code Playgroud)

或者es

@{find $1} /tmp
Run Code Online (Sandbox Code Playgroud)

要永久更改当前位置参数,语法取决于 shell。dchirikov 已经涵盖了 Bourne-like shell (Bourne, Korn, bash, zsh, POSIX ash, yash...)。

语法是:

set arg1 arg2 ... argn
Run Code Online (Sandbox Code Playgroud)

但是,您需要:

set --
Run Code Online (Sandbox Code Playgroud)

清空该列表(或shift "$#")和

set -- -foo
Run Code Online (Sandbox Code Playgroud)

设置$1为以-or开头的内容+,因此始终使用它是一个好习惯,set --尤其是在使用任意数据时,例如set -- "$@" other-arg将参数添加到位置参数列表的末尾。

csh系列 ( csh, tcsh) 的外壳中,您分配给argv数组:

set argv=(arg1 arg2)
Run Code Online (Sandbox Code Playgroud)

rc家族 ( rc, es, akanga) 的shell 中,到*数组:

*=(arg1 arg2)
Run Code Online (Sandbox Code Playgroud)

虽然您也可以单独分配元素:

2=arg2
Run Code Online (Sandbox Code Playgroud)

fish,位置参数是在argv阵列(无$1$@那里):

set argv arg1 arg2
Run Code Online (Sandbox Code Playgroud)

在 中zsh,为了与 兼容csh,您还可以分配给argv数组:

argv=(arg1 arg2)
argv[4]=arg4
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

5=arg5
Run Code Online (Sandbox Code Playgroud)

这意味着您还可以执行以下操作:

argv+=(another-arg)
Run Code Online (Sandbox Code Playgroud)

在末尾添加一个参数,并且:

argv[-1]=()
argv[2]=()
Run Code Online (Sandbox Code Playgroud)

从末尾或中间删除参数,这是其他 shell 无法轻松做到的。


dch*_*kov 7

set --
Run Code Online (Sandbox Code Playgroud)

是你需要的:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
Run Code Online (Sandbox Code Playgroud)