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

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

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

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

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

以及其他组合。还尝试了添加 shebang 解释器指令#!/bin/sh -x,但没有得到想要的结果。

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

答案1

之后的第一个参数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 已经流行并且公开可用,这些 shell 已经消失了)。


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

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

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

(){find "$1"} /tmp

或者es

@{find $1} /tmp

要永久更改当前位置参数,语法取决于 shell。dchirikov 已经覆盖了类似 Bourne 的外壳(伯恩、科恩、、、bashPOSIX zsh、、ash... yash)。

语法是:

set arg1 arg2 ... argn

但是,您需要:

set --

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

set -- -foo

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

csh在系列 ( csh, )的 shell 中tcsh,您可以分配给argv数组:

set argv=(arg1 arg2)

rc在系列 ( rc, es, )的 shell 中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]=()

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

答案2

set --

是你所需要的:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc

相关内容