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


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是语法错误。您能以不同的方式解释您要做什么吗?
Celada 2014年

2
@Celada,这不是在贝壳语法错误rc的家庭(rcesakanga...),其中这相当于情况find $1 /tmp
斯特凡Chazelas

Answers:


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第一个arg进入的实现$1,因此您可以执行以下操作:

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

要么:

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

考虑到这两种行为,但是由于POSIX流行并且可以公开使用,所以这些shell已经消失了)。


如果要在当前shell的本地范围内设置$1,则可以$2在其中使用函数。在类似伯恩的贝壳中:

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

一些外壳程序支持匿名功能。是这样的zsh

(){find "$1"} /tmp

es

@{find $1} /tmp

要永久更改当前位置参数,语法取决于外壳。dchirikov已经涵盖了类似Bourne外壳(伯恩,科恩,bashzsh,POSIX, ashyash...)。

语法为:

set arg1 arg2 ... argn

但是,您需要:

set --

要清空该列表(或shift "$#"),然后

set -- -foo

设置$1为以-或开头的内容+,因此,总是习惯使用set --这种习惯,尤其是在使用任意数据(例如set -- "$@" other-arg在位置参数列表的末尾添加参数)时。

csh族(cshtcsh)的外壳程序中,您分配给该argv数组:

set argv=(arg1 arg2)

在的壳rc家族(rcesakanga),于*数组:

*=(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则很难做到这一点。


7
set --

您需要的是:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.