给定一个需要一些参数的程序,例如program -in file.in -out file.out,编写一个可以使用或不使用任何这些参数调用并为每个参数使用默认值的 bash 脚本的最简单方法是什么?
script -in otherfile会跑program -in otherfile -out file.out,
script -out otherout -furtherswitch会跑program -in file.in -out otherout -furtherswitch等等。
这两个文件都用于将参数传递给内核。那么两者到底有什么区别呢?每个文件的用途是什么?
最近我正在对sed配置文件执行操作。我发现该sed命令的行为与参数-irvs不同-ri:-
[root@node system]# sed -ri 's|(^[[:space:]]+[Kk]ernel.*$)|\1 transparent_hugepage=never|' temp_file
[root@node system]# echo $?
0
[root@node system]# sed -ir 's|(^[[:space:]]+[Kk]ernel.*$)|\1 transparent_hugepage=never|' temp_file
sed: -e expression #1, char 60: invalid reference \1 on `s' command's RHS
[root@node system]# echo $?
1
Run Code Online (Sandbox Code Playgroud) 我已阅读,位置参数在开始$1(例如:$1,$2,$3等等是位置参数)。但$0不是位置参数。
但为什么$0不是位置参数?
我认为这可能是一个原因,但不确定:
位置参数仅在执行脚本时采用它们的值。例如:如果我们这样做./myScript Hello,那么$1将有值Hello。但是$0可以在两种情况下取其值:执行脚本时(它将具有脚本名称的值),以及在bash没有脚本的情况下执行自身时(它将具有值bashor -bash)。
我读过这$@是一个保存位置参数的数组。
我试图输出$@数组的一个元素:
echo ${@[1]}
Run Code Online (Sandbox Code Playgroud)
但是bash给了我这个错误:
test.sh: line 1: ${@[1]}: bad substitution
Run Code Online (Sandbox Code Playgroud) 所以我正在测试以下内容:
foo() {
printf "\nAll the parameters, each on a separate line:\n"
printf "param: %s\n" "$@"
}
foo The "nicely colored" rainbow
Run Code Online (Sandbox Code Playgroud)
输出是:
All the parameters:
param: The
param: nicely colored
param: rainbow
Run Code Online (Sandbox Code Playgroud)
所以如果我理解正确,因为IFS设置为\t\n我们得到由制表符分隔的参数( 的第一个字符IFS)。
但是为什么它们被打印在不同的行中?
是为每个参数运行 printf 。即 bash 是否将其转换为 for 循环?
以下(不带双引号)也输出相同的结果:
printf "param: %s\n" $@
AIX 上的一个脚本,它检查传递的参数数量并在它们不正确时进行抱怨:-
if [ "$#" -ge 1 ]; then
...
else
echo 'Usage: myscript <a> [b] [c]'
fi
Run Code Online (Sandbox Code Playgroud)
该脚本设置了一些环境变量,因此它是来源。我的意思是我在命令行上输入以下内容。没有第二个脚本,我不是从另一个脚本中获取脚本。
. ./myscript.sh
Run Code Online (Sandbox Code Playgroud)
如果我不传递任何参数,我希望它打印出使用语句,但它会使用传递给上一个源命令的参数运行(甚至不一定是这个脚本!)。
为了仔细检查这一点,我在脚本的开头添加了这一行以证明情况确实如此。
echo $# $@
Run Code Online (Sandbox Code Playgroud)
如果我不传递任何参数,它会打印出来自先前来源脚本的编号和参数列表。
$#当我传递零参数并获取它时,如何让它说为零?
最小可能的重新创建是一个脚本,因此:-
脚本文件
echo $# $@
Run Code Online (Sandbox Code Playgroud)
然后运行它: -
. ./myscript.sh a b c
Run Code Online (Sandbox Code Playgroud)
打印出来
3 a b c
Run Code Online (Sandbox Code Playgroud)
然后在没有任何参数的情况下再次运行它:-
. ./myscript.sh
Run Code Online (Sandbox Code Playgroud)
打印出相同的
3 a b c
Run Code Online (Sandbox Code Playgroud)
什么时候打印出来
0
Run Code Online (Sandbox Code Playgroud)
如果您不提供脚本并直接运行它:-
./myscript.sh
Run Code Online (Sandbox Code Playgroud)
然后它按预期工作并打印出来
0
Run Code Online (Sandbox Code Playgroud)
我希望这能澄清手头的问题。
由于我似乎得到了很多答案来解释为什么上述方法不起作用,并且没有答案告诉我我应该做什么,我想我会再尝试一次尝试解释我正在尝试做的事情。
要求
我需要编写一个需要至少一个参数的脚本,如果没有使用所述参数调用它就会抱怨(请参阅上面问题中的第一个代码块),并且该脚本需要设置一些环境变量。由于第二个要求,我假设我需要获取脚本的来源,以便在脚本完成时仍然设置环境变量。你怎么能写一个脚本来告诉它什么时候没有传递参数,也可以设置环境变量?
每个人都知道find . -exec foo {} \;,但在某个时候就停止了思考。但最近我又回到了我第一次学习时出现的问题:
为什么有人会选择
{}作为路径/名称的占位符?
如果您必须指定语法,您可能会使用某种$组合,就像它们用于许多其他语言中的变量参数一样。作为一名 C 程序员,人们可能会想%在printf. 甚至@会觉得这是一个自然的选择。或者一些在该上下文中没有特殊含义的“自由”字符。但为什么是一对大括号里面什么都没有呢?牙套总是用来收集里面的东西。对我来说,这似乎是最奇怪的想法。
我知道大部分历史find似乎都迷失在不确定性中,但也许有人知道一些以类似方式使用花括号的早期工具?
你好,我有这个 ~/.bash_profile
export GOPATH="$HOME/go_projects"
export GOBIN="$GOPATH/bin"
program(){
$GOBIN/program $1
}
Run Code Online (Sandbox Code Playgroud)
所以我能够做到program "-p hello_world -tSu"。有没有办法在不使用引号的情况下运行程序和自定义标志?如果我这样做,program -p hello_world -tSu它只会使用-p标志,空格后的所有内容都将被忽略。
哪个是正确的方法- 用空格将参数与参数分开,还是没有?
你应该分开争论还是把它们粘在一起?
例子:
<command> -D 192.168.0.100 -p 80
<command> -cvvfz
Run Code Online (Sandbox Code Playgroud)
或者:
<command> -D192.168.0.100 -p80
<command> -c -vv -f -z
Run Code Online (Sandbox Code Playgroud)
某些程序是否只接受一种“风格”,或者一般来说根本不重要?