有时需要在小示例中模拟和验证上述变量,然后可以立即复制到某些脚本等中。
我尝试通过以下方式使用一个简单的示例来解决:
(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 的外壳(伯恩、科恩、、、bash
POSIX 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