如何使用bash/shell更改argv[0]值?

如何使用bash/shell更改argv[0]值?,bash,shell,sh,Bash,Shell,Sh,脚本应该能够更改shell/bash脚本中的argv[0]值。 我在一篇老帖子上找到了它,但我无法真正理解它在做什么。 有人能解释一下这条线是怎么工作的吗 sh -c ". '$0'" argv0new "$@" test.“$INNERCALL”也是一个变量吗 原始问题: 当变量INNERCALL未设置时,脚本使用一组特定的参数调用自己。它设置变量以避免无限循环,然后以允许脚本设置自己的$0的方式调用自身。然后,内部实例在测试之外执行代码,这表明$0现在确实设置为脚本作者选择的特定值。完成后

脚本应该能够更改shell/bash脚本中的argv[0]值。 我在一篇老帖子上找到了它,但我无法真正理解它在做什么。 有人能解释一下这条线是怎么工作的吗

sh -c ". '$0'" argv0new "$@"
test.“$INNERCALL”
也是一个变量吗

原始问题:


当变量
INNERCALL
未设置时,脚本使用一组特定的参数调用自己。它设置变量以避免无限循环,然后以允许脚本设置自己的
$0
的方式调用自身。然后,内部实例在
测试
之外执行代码,这表明
$0
现在确实设置为脚本作者选择的特定值。完成后,我们返回到脚本的外部实例,然后该实例简单地退出


真正重要的是
sh-c'script…”arg0 arg1 arg2
$0
设置为脚本本身后的第一个参数(
arg0
),当变量
INNERCALL
未设置时,脚本使用一组特定的参数调用自身。它设置变量以避免无限循环,然后以允许脚本设置自己的
$0
的方式调用自身。然后,内部实例在
测试
之外执行代码,这表明
$0
现在确实设置为脚本作者选择的特定值。完成后,我们返回到脚本的外部实例,然后该实例简单地退出


真正重要的是
sh-c'script…”arg0 arg1 arg2
$0
设置为脚本本身之后的第一个参数(
arg0
,在本例中)。

注意,它不会更改argv0的值,而是使用argv0new创建一个新进程

改变

sh -c ". '$0'" argv0new "$@"

也可以通过sh改变bash

狂欢节

-c

从第一个非选项参数command_字符串读取并执行命令,然后退出。如果命令_字符串后面有参数,则第一个参数将指定给$0,其余参数将指定给位置参数。$0的赋值设置shell的名称,用于警告和错误消息


注意,它不会更改argv0的值,而是使用argv0new创建一个新进程

改变

sh -c ". '$0'" argv0new "$@"

也可以通过sh改变bash

狂欢节

-c

从第一个非选项参数command_字符串读取并执行命令,然后退出。如果命令_字符串后面有参数,则第一个参数将指定给$0,其余参数将指定给位置参数。$0的赋值设置shell的名称,用于警告和错误消息


让我们一行一行地看一遍

测试“$INNERCALL”=.是

基本上,这会看到
$INNERCALL
中是否已经有
YES
值。Shell的
函数以安全的方式进行变量扩展,并将其全部封送到一个值中,例如

foo="hello"
bar=", world!"
echo "foobar is: $foo$bar"
打印
foobar是:你好,世界


这使用
|
运算符表示,如果上一个程序返回了非零值(例如,如果相关条件为false,则是返回1的程序),则执行此代码块,否则跳过它(有关
|
的详细信息,请参阅)


这将
INNERCALL
设置为
YES
,这意味着这只在第一级执行


这就是魔法发生的地方
sh-c
打开一个新的shell,然后从后面的字符串中读取其参数<代码>“%$0”
对当前位于
$0
的值使用
sh
的源函数,该值应为当前文件

基本上,
sh-c.“$0”
只是在子
sh
过程中再次打开当前文件,然后该行的其余部分替换参数:
argv0new
将成为新的$0,您还可以通过包含
“$@”

然后
exit$?
返回子进程运行的任何返回值

代码的其余部分只是为了证明除了
$0
之外的所有参数都是相同的,
$0
已被替换



tl;dr它打开一个子shell进程,告诉它读取当前文件,替换参数,然后导出一个测试值,这样它就不会无限循环。

让我们一行一行地看一下这个过程

测试“$INNERCALL”=.是

基本上,这会看到
$INNERCALL
中是否已经有
YES
值。Shell的
函数以安全的方式进行变量扩展,并将其全部封送到一个值中,例如

foo="hello"
bar=", world!"
echo "foobar is: $foo$bar"
打印
foobar是:你好,世界


这使用
|
运算符表示,如果上一个程序返回了非零值(例如,如果相关条件为false,则是返回1的程序),则执行此代码块,否则跳过它(有关
|
的详细信息,请参阅)


这将
INNERCALL
设置为
YES
,这意味着这只在第一级执行


这就是魔法发生的地方
sh-c
打开一个新的shell,然后从后面的字符串中读取其参数<代码>“%$0”
对当前位于
$0
的值使用
sh
的源函数,该值应为当前文件

基本上,
sh-c.“$0”
只是在子
sh
过程中再次打开当前文件,然后该行的其余部分替换参数:
argv0new
将成为新的$0,您还可以通过包含
“$@”

然后
exit$?
返回子进程运行的任何返回值|| { ... }
export INNERCALL=YES
sh -c ". '$0'" argv0new "$@"
exit $?