Linux Bash 中的 eval 命令及其典型用途
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11065077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
eval command in Bash and its typical uses
提问by kstratis
After reading the bash man pages and with respect to this post.
在阅读了 bash 手册页和这篇文章之后。
I am still having trouble understanding what exactly the eval
command does and which would be its typical uses. For example if we do:
我仍然无法理解eval
命令的作用以及它的典型用途。例如,如果我们这样做:
bash$ set -- one two three # sets
bash$ echo
one
bash$ n=1
bash$ echo ${$n} ## First attempt to echo using brackets fails
bash: ${$n}: bad substitution
bash$ echo $($n) ## Second attempt to echo using parentheses fails
bash: 1: command not found
bash$ eval echo ${$n} ## Third attempt to echo using 'eval' succeeds
one
What exactly is happening here and how do the dollar sign and the backslash tie into the problem?
这里到底发生了什么,美元符号和反斜杠如何与问题联系起来?
采纳答案by Gilles 'SO- stop being evil'
eval
takes a string as its argument, and evaluates it as if you'd typed that string on a command line. (If you pass several arguments, they are first joined with spaces between them.)
eval
接受一个字符串作为其参数,并像您在命令行中键入该字符串一样对其进行评估。(如果你传递多个参数,它们首先用它们之间的空格连接。)
${$n}
is a syntax error in bash. Inside the braces, you can only have a variable name, with some possible prefix and suffixes, but you can't have arbitrary bash syntax and in particular you can't use variable expansion. There is a way of saying “the value of the variable whose name is in this variable”, though:
${$n}
是 bash 中的语法错误。在大括号内,您只能有一个变量名,带有一些可能的前缀和后缀,但不能有任意的 bash 语法,特别是不能使用变量扩展。不过,有一种说法是“名称在此变量中的变量的值”:
echo ${!n}
one
$(…)
runs the command specified inside the parentheses in a subshell (i.e. in a separate process that inherits all settings such as variable values from the current shell), and gathers its output. So echo $($n)
runs $n
as a shell command, and displays its output. Since $n
evaluates to 1
, $($n)
attempts to run the command 1
, which does not exist.
$(…)
在子shell 中运行括号内指定的命令(即在继承所有设置的单独进程中,例如来自当前shell 的变量值),并收集其输出。So作为 shell 命令echo $($n)
运行$n
,并显示其输出。由于$n
计算为1
,因此$($n)
尝试运行1
不存在的命令。
eval echo \${$n}
runs the parameters passed to eval
. After expansion, the parameters are echo
and ${1}
. So eval echo \${$n}
runs the command echo ${1}
.
eval echo \${$n}
运行传递给eval
. 展开后,参数为echo
和${1}
。所以eval echo \${$n}
运行命令echo ${1}
。
Note that most of the time, you must use double quotes around variable substitutions and command substitutions (i.e. anytime there's a $
): "$foo", "$(foo)"
. Always put double quotes around variable and command substitutions, unless you know you need to leave them off. Without the double quotes, the shell performs field splitting (i.e. it splits value of the variable or the output from the command into separate words) and then treats each word as a wildcard pattern. For example:
请注意,大多数情况下,您必须在变量替换和命令替换周围使用双引号(即,只要有$
): "$foo", "$(foo)"
。总是在变量和命令替换周围加上双引号,除非你知道你需要把它们去掉。如果没有双引号,shell 将执行字段拆分(即将变量的值或命令的输出拆分为单独的单词),然后将每个单词视为通配符模式。例如:
$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo ""
f* *
$ echo
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo ${$n}
file1 file2 file1 file2 otherfile
$eval echo \"${$n}\"
f* *
$ echo "${!n}"
f* *
eval
is not used very often. In some shells, the most common use is to obtain the value of a variable whose name is not known until runtime. In bash, this is not necessary thanks to the ${!VAR}
syntax. eval
is still useful when you need to construct a longer command containing operators, reserved words, etc.
eval
不经常使用。在某些 shell 中,最常见的用途是获取名称直到运行时才知道的变量的值。在 bash 中,由于${!VAR}
语法的原因,这不是必需的。eval
当您需要构造包含运算符、保留字等的更长命令时,它仍然很有用。
回答by Hari Menon
Simply think of eval as "evaluating your expression one additional time before execution"
简单地将 eval 视为“在执行前额外评估一次表达式”
eval echo \${$n}
becomes echo $1
after the first round of evaluation. Three changes to notice:
eval echo \${$n}
成为echo $1
第一轮评估后。需要注意的三个变化:
- The
\$
became$
(The backslash is needed, otherwise it tries to evaluate${$n}
, which means a variable named{$n}
, which is not allowed) $n
was evaluated to1
- The
eval
disappeared
- 的
\$
成为$
(需要反斜杠,否则它会尝试来评估${$n}
的,这意味着一个命名的变量{$n}
,这是不允许的) $n
被评估为1
- 将
eval
消失
In the second round, it is basically echo $1
which can be directly executed.
第二轮基本echo $1
是可以直接执行的。
So eval <some command>
will first evaluate <some command>
(by evaluate here I mean substitute variables, replace escaped characters with the correct ones etc.), and then run the resultant expression once again.
所以eval <some command>
将首先评估<some command>
(这里的评估是指替换变量,用正确的字符替换转义字符等),然后再次运行结果表达式。
eval
is used when you want to dynamically create variables, or to read outputs from programs specifically designed to be read like this. See http://mywiki.wooledge.org/BashFAQ/048for examples. The link also contains some typical ways in which eval
is used, and the risks associated with it.
eval
用于动态创建变量,或从专门设计为这样读取的程序中读取输出。有关示例,请参阅http://mywiki.wooledge.org/BashFAQ/048。该链接还包含一些典型的使用方式eval
以及与之相关的风险。
回答by Nikhil Gupta
The eval statement tells the shell to take eval's arguments as command and run them through the command-line. It is useful in a situation like below:
eval 语句告诉 shell 将 eval 的参数作为命令并通过命令行运行它们。它在以下情况下很有用:
In your script if you are defining a command into a variable and later on you want to use that command then you should use eval:
在你的脚本中,如果你将一个命令定义到一个变量中,然后你想使用该命令,那么你应该使用 eval:
/home/user1 > a="ls | more"
/home/user1 > $a
bash: command not found: ls | more
/home/user1 > # Above command didn't work as ls tried to list file with name pipe (|) and more. But these files are not there
/home/user1 > eval $a
file.txt
mailids
remote_cmd.sh
sample.txt
tmp
/home/user1 >
回答by sootsnoot
In my experience, a "typical" use of eval is for running commands that generate shell commands to set environment variables.
根据我的经验,eval 的“典型”用途是运行生成 shell 命令来设置环境变量的命令。
Perhaps you have a system that uses a collection of environment variables, and you have a script or program that determines which ones should be set and their values. Whenever you run a script or program, it runs in a forked process, so anything it does directly to environment variables is lost when it exits. But that script or program can send the export commands to stdout.
也许您有一个使用环境变量集合的系统,并且您有一个脚本或程序来确定应该设置哪些变量及其值。每当您运行脚本或程序时,它都会在分叉进程中运行,因此当它退出时,它直接对环境变量所做的任何事情都会丢失。但是该脚本或程序可以将导出命令发送到标准输出。
Without eval, you would need to redirect stdout to a temp file, source the temp file, and then delete it. With eval, you can just:
如果没有 eval,您需要将 stdout 重定向到临时文件,获取临时文件,然后将其删除。使用 eval,您可以:
eval "$(script-or-program)"
Note the quotes are important. Take this (contrived) example:
注意引号很重要。以这个(人为的)例子为例:
# activate.sh
echo 'I got activated!'
# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")
$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!
回答by YoYo
I like the "evaluating your expression one additional time before execution" answer, and would like to clarify with another example.
我喜欢“在执行前额外评估一次表达式”的答案,并想用另一个例子来澄清。
var="\"par1 par2\""
echo $var # prints nicely "par1 par2"
function cntpars() {
echo " > Count: $#"
echo " > Pars : $*"
echo " > par1 : "
echo " > par2 : "
if [[ $# = 1 && = "par1 par2" ]]; then
echo " > PASS"
else
echo " > FAIL"
return 1
fi
}
# Option 1: Will Pass
echo "eval \"cntpars $var\""
eval "cntpars $var"
# Option 2: Will Fail, with curious results
echo "cntpars $var"
cntpars $var
The Curious results in Option 2 are that we would have passed 2 parameters as follows:
选项 2 中的 Curious 结果是我们将按如下方式传递 2 个参数:
- First Parameter:
"value
- Second Parameter:
content"
- 第一个参数:
"value
- 第二个参数:
content"
How is that for counter intuitive? The additional eval
will fix that.
反直觉如何?额外的eval
将解决这个问题。
Adapted from https://stackoverflow.com/a/40646371/744133
回答by Paul
In the question:
在问题中:
who | grep $(tty | sed s:/dev/::)
outputs errors claiming that files a and tty do not exist. I understood this to mean that tty is not being interpreted before execution of grep, but instead that bash passed tty as a parameter to grep, which interpreted it as a file name.
输出错误,声称文件 a 和 tty 不存在。我理解这意味着在执行 grep 之前不会解释 tty,而是 bash 将 tty 作为参数传递给 grep,grep 将其解释为文件名。
There is also a situation of nested redirection, which should be handled by matched parentheses which should specify a child process, but bash is primitively a word separator, creating parameters to be sent to a program, therefore parentheses are not matched first, but interpreted as seen.
还有一种嵌套重定向的情况,应该通过匹配的括号来处理,它应该指定一个子进程,但是bash原始是一个单词分隔符,创建要发送给程序的参数,因此括号不是先匹配,而是解释为看到了。
I got specific with grep, and specified the file as a parameter instead of using a pipe. I also simplified the base command, passing output from a command as a file, so that i/o piping would not be nested:
我对 grep 进行了具体说明,并将文件指定为参数而不是使用管道。我还简化了基本命令,将命令的输出作为文件传递,这样 i/o 管道就不会嵌套:
grep $(tty | sed s:/dev/::) <(who)
works well.
效果很好。
who | grep $(echo pts/3)
is not really desired, but eliminates the nested pipe and also works well.
并不是真正需要的,但消除了嵌套管道并且也运行良好。
In conclusion, bash does not seem to like nested pipping. It is important to understand that bash is not a new-wave program written in a recursive manner. Instead, bash is an old 1,2,3 program, which has been appended with features. For purposes of assuring backward compatibility, the initial manner of interpretation has never been modified. If bash was rewritten to first match parentheses, how many bugs would be introduced into how many bash programs? Many programmers love to be cryptic.
总之,bash 似乎不喜欢嵌套的 pipping。bash 不是以递归方式编写的新浪潮程序,了解这一点很重要。相反,bash 是一个旧的 1,2,3 程序,它附加了一些特性。为了确保向后兼容性,从未修改过最初的解释方式。如果将 bash 重写为首先匹配括号,将在多少个 bash 程序中引入多少错误?许多程序员喜欢神秘。
回答by clearlight
Update: Some people say one should -never- use eval. I disagree. I think the risk arises when corrupt input can be passed to eval
. However there are many common situations where that is not a risk, and therefore it is worth knowing how to use eval in any case. This stackoverflow answerexplains the risks of eval and alternatives to eval. Ultimately it is up to the user to determine if/when eval is safe and efficient to use.
更新:有人说应该 - 永远不要 - 使用 eval。我不同意。我认为当损坏的输入可以传递给eval
. 但是,在许多常见情况下,这不是风险,因此在任何情况下都值得了解如何使用 eval。这个stackoverflow 答案解释了 eval 的风险和 eval 的替代方案。最终由用户决定 eval 是否/何时使用安全有效。
The bash eval
statement allows you to execute lines of code calculated or acquired, by your bash script.
basheval
语句允许您执行由 bash 脚本计算或获取的代码行。
Perhaps the most straightforward example would be a bash program that opens another bash script as a text file, reads each line of text, and uses eval
to execute them in order. That's essentially the same behavior as the bash source
statement, which is what one would use, unless it was necessary to perform some kind of transformation (e.g. filtering or substitution) on the content of the imported script.
也许最直接的例子是一个 bash 程序,它将另一个 bash 脚本作为文本文件打开,读取每一行文本,并按eval
顺序执行它们。这与 bashsource
语句的行为本质上是相同的,这是人们会使用的,除非有必要对导入的脚本的内容执行某种转换(例如过滤或替换)。
I rarely have needed eval
, but I have found it useful to read or write variables whose nameswere contained in strings assigned to other variables. For example, to perform actions on sets of variables, while keeping the code footprint small and avoiding redundancy.
我很少需要eval
,但我发现读取或写入名称包含在分配给其他变量的字符串中的变量很有用。例如,对变量集执行操作,同时保持较小的代码占用空间并避免冗余。
eval
is conceptually simple. However, the strict syntax of the bash language, and the bash interpreter's parsing order can be nuanced and make eval
appear cryptic and difficult to use or understand. Here are the essentials:
eval
概念上很简单。但是,bash 语言的严格语法和 bash 解释器的解析顺序可能会细微差别,使eval
显得神秘且难以使用或理解。以下是要点:
The argument passed to
eval
is a string expressionthat is calculated at runtime.eval
will execute the final parsed result of its argument as an actualline of code in your script.Syntax and parsing order are stringent. If the result isn't an executable line of bash code, in scope of your script, the program will crash on the
eval
statement as it tries to execute garbage.When testing you can replace the
eval
statement withecho
and look at what is displayed. If it is legitimate code in the current context, running it througheval
will work.
传递给的参数是在运行时计算
eval
的字符串表达式。eval
将其参数的最终解析结果作为脚本中的实际代码行执行。语法和解析顺序是严格的。如果结果不是可执行的 bash 代码行,则在脚本范围内,程序将在
eval
尝试执行垃圾时在语句上崩溃。测试时,您可以将
eval
语句替换为echo
并查看显示的内容。如果它是当前上下文中的合法代码,则运行它eval
会起作用。
The following examples may help clarify how eval works...
以下示例可能有助于阐明 eval 的工作原理...
Example 1:
示例 1:
eval
statement in front of 'normal' code is a NOP
eval
“正常”代码前面的语句是 NOP
$ eval a=b
$ eval echo $a
b
In the above example, the first eval
statements has no purpose and can be eliminated. eval
is pointless in the first line because there is no dynamic aspect to the code, i.e. it already parsed into the final lines of bash code, thus it would be identical as a normal statement of code in the bash script. The 2nd eval
is pointless too, because, although there is a parsing step converting $a
to its literal string equivalent, there is no indirection (e.g. no referencing via string value of an actualbash noun or bash-held script variable), so it would behave identically as a line of code without the eval
prefix.
在上面的例子中,第一条eval
语句没有任何意义,可以删除。eval
第一行没有意义,因为代码没有动态方面,即它已经解析为 bash 代码的最后几行,因此它与 bash 脚本中的普通代码语句相同。第二个eval
也是毫无意义的,因为虽然有一个解析步骤转换$a
为其等效的文字字符串,但没有间接(例如,没有通过实际bash 名词或 bash 持有的脚本变量的字符串值进行引用),所以它的行为是相同的作为没有eval
前缀的一行代码。
Example 2:
示例 2:
Perform var assignment using var names passed as string values.
使用作为字符串值传递的 var 名称执行 var 赋值。
$ key="mykey"
$ val="myval"
$ eval $key=$val
$ echo $mykey
myval
If you were to echo $key=$val
, the output would be:
如果你要echo $key=$val
,输出将是:
mykey=myval
That, being the final result of string parsing, is what will be executed by eval, hence the result of the echo statement at the end...
那,作为字符串解析的最终结果,将被 eval 执行,因此最后的 echo 语句的结果......
Example 3:
示例 3:
Adding more indirection to Example 2
向示例 2 添加更多间接
$ keyA="keyB"
$ valA="valB"
$ keyB="that"
$ valB="amazing"
$ eval eval $$keyA=$$valA
$ echo $that
amazing
The above is a bit more complicated than the previous example, relying more heavily on the parsing-order and peculiarities of bash. The eval
line would roughly get parsed internally in the following order (note the following statements are pseudocode, not real code, just to attempt to show how the statement would get broken down into steps internally to arrive at the final result).
上面的例子比前面的例子稍微复杂一些,更多地依赖于 bash 的解析顺序和特性。该eval
行将按以下顺序在内部粗略地解析(请注意,以下语句是伪代码,不是真正的代码,只是为了尝试展示该语句如何在内部分解为步骤以得出最终结果)。
eval eval $$keyA=$$valA # substitution of $keyA and $valA by interpreter
eval eval $keyB=$valB # convert '$' + name-strings to real vars by eval
eval $keyB=$valB # substitution of $keyB and $valB by interpreter
eval that=amazing # execute string literal 'that=amazing' by eval
If the assumed parsing order doesn't explain what eval is doing enough, the third example may describe the parsing in more detail to help clarify what is going on.
如果假定的解析顺序不能充分解释 eval 的作用,则第三个示例可能会更详细地描述解析以帮助阐明发生了什么。
Example 4:
示例 4:
Discover whether vars, whose namesare contained in strings, themselves contain string values.
发现名称包含在字符串中的变量本身是否包含字符串值。
a="User-provided"
b="Another user-provided optional value"
c=""
myvarname_a="a"
myvarname_b="b"
myvarname_c="c"
for varname in "myvarname_a" "myvarname_b" "myvarname_c"; do
eval varval=$$varname
if [ -z "$varval" ]; then
read -p "$varname? " $varname
fi
done
In the first iteration:
在第一次迭代中:
varname="myvarname_a"
Bash parses the argument to eval
, and eval
sees literally this at runtime:
Bash 将参数解析为eval
,并eval
在运行时看到字面意思:
eval varval=$$myvarname_a
The following pseudocodeattempts to illustrate howbash interprets the above line of realcode, to arrive at the final value executed by eval
. (the following lines descriptive, not exact bash code):
下面的伪代码试图说明bash如何解释上面这行实际代码,以得出eval
. (以下几行是描述性的,而不是确切的 bash 代码):
1. eval varval="$" + "$varname" # This substitution resolved in eval statement
2. .................. "$myvarname_a" # $myvarname_a previously resolved by for-loop
3. .................. "a" # ... to this value
4. eval "varval=$a" # This requires one more parsing step
5. eval varval="User-provided" # Final result of parsing (eval executes this)
Once all the parsing is done, the result is what is executed, and its effect is obvious, demonstrating there is nothing particularly mysterious about eval
itself, and the complexity is in the parsingof its argument.
一旦所有的解析完成,结果就是执行的,它的效果是显而易见的,证明eval
它本身并没有什么特别神秘的,复杂的是它的参数的解析。
varval="User-provided"
The remaining code in the example above simply tests to see if the value assigned to $varval is null, and, if so, prompts the user to provide a value.
上面示例中的其余代码只是测试分配给 $varval 的值是否为空,如果是,则提示用户提供一个值。
回答by flabdablet
I've recently had to use eval
to force multiple brace expansions to be evaluated in the order I needed. Bash does multiple brace expansions from left to right, so
我最近不得不使用eval
强制按我需要的顺序评估多个大括号扩展。Bash 从左到右做了多个大括号扩展,所以
xargs -I_ cat _/{11..15}/{8..5}.jpg
expands to
扩展到
xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg
but I needed the second brace expansion done first, yielding
但我需要先完成第二个大括号扩展,产生
xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg
The best I could come up with to do that was
我能想到的最好的办法是
xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)
This works because the single quotes protect the first set of braces from expansion during the parsing of the eval
command line, leaving them to be expanded by the subshell invoked by eval
.
这是有效的,因为在解析eval
命令行期间,单引号保护第一组大括号不被扩展,让它们由eval
.
There may be some cunning scheme involving nested brace expansions that allows this to happen in one step, but if there is I'm too old and stupid to see it.
可能有一些涉及嵌套大括号扩展的狡猾计划允许这一步发生,但如果有的话,我太老太笨了,看不到它。
回答by Luke Pafford
I originally intentionally never learned how to use eval, because most people will recommend to stay away from it like the plague. However I recently discovered a use case that made me facepalm for not recognizing it sooner.
我本来是故意没学过eval的,因为大部分人会建议远离它,就像瘟疫一样。然而,我最近发现了一个用例,让我因为没有早点认识到它而脸红。
If you have cron jobs that you want to run interactively to test, you might view the contents of the file with cat, and copy and paste the cron job to run it. Unfortunately, this involves touching the mouse, which is a sin in my book.
如果您有想要以交互方式运行以进行测试的 cron 作业,您可以使用 cat 查看文件的内容,然后复制并粘贴 cron 作业以运行它。不幸的是,这涉及到触摸鼠标,这在我的书中是一种罪过。
Lets say you have a cron job at /etc/cron.d/repeatme with the contents:
假设您在 /etc/cron.d/repeatme 有一个 cron 作业,内容如下:
*/10 * * * * root program arg1 arg2
*/10 * * * * root program arg1 arg2
You cant execute this as a script with all the junk in front of it, but we can use cut to get rid of all the junk, wrap it in a subshell, and execute the string with eval
你不能把它作为一个脚本来执行,前面有所有的垃圾,但我们可以使用 cut 摆脱所有的垃圾,把它包装在一个子壳中,然后用 eval 执行字符串
eval $( cut -d ' ' -f 6- /etc/cron.d/repeatme)
eval $( cut -d ' ' -f 6- /etc/cron.d/repeatme)
The cut command only prints out the 6th field of the file, delimited by spaces. Eval then executes that command.
cut 命令仅打印出文件的第 6 个字段,以空格分隔。然后 Eval 执行该命令。
I used a cron job here as an example, but the concept is to format text from stdout, and then evaluate that text.
我在这里使用 cron 作业作为示例,但其概念是从 stdout 格式化文本,然后评估该文本。
The use of eval in this case is not insecure, because we know exactly what we will be evaluating before hand.
在这种情况下使用 eval 并不是不安全的,因为我们事先确切地知道我们将要评估的内容。
回答by Craig Hicks
You asked about typical uses.
您询问了典型用途。
One common complaint about shell scripting is that you (allegedly) can't pass by reference to get values back out of functions.
关于 shell 脚本的一个常见抱怨是您(据称)无法通过引用传递来从函数中取回值。
But actually, via "eval", you canpass by reference. The callee can pass back a list of variable assignments to be evaluated by the caller. It is pass by reference because the caller can allowed to specify the name(s) of the result variable(s) - see example below. Error results can be passed back standard names like errno and errstr.
但实际上,通过“eval”,您可以通过引用传递。被调用者可以传回要由调用者评估的变量赋值列表。它是通过引用传递的,因为调用者可以允许指定结果变量的名称 - 请参见下面的示例。错误结果可以传递回标准名称,如 errno 和 errstr。
Here is an example of passing by reference in bash:
这是在 bash 中按引用传递的示例:
#!/bin/bash
isint()
{
re='^[-]?[0-9]+$'
[[ =~ $re ]]
}
#args 1: name of result variable, 2: first addend, 3: second addend
iadd()
{
if isint && isint ; then
echo "=$((+));errno=0"
return 0
else
echo "errstr=\"Error: non-integer argument to iadd $*\" ; errno=329"
return 1
fi
}
var=1
echo "[1] var=$var"
eval $(iadd var A B)
if [[ $errno -ne 0 ]]; then
echo "errstr=$errstr"
echo "errno=$errno"
fi
echo "[2] var=$var (unchanged after error)"
eval $(iadd var $var 1)
if [[ $errno -ne 0 ]]; then
echo "errstr=$errstr"
echo "errno=$errno"
fi
echo "[3] var=$var (successfully changed)"
The output looks like this:
输出如下所示:
[1] var=1
errstr=Error: non-integer argument to iadd var A B
errno=329
[2] var=1 (unchanged after error)
[3] var=2 (successfully changed)
There is almost unlimitedband width in that text output! And there are more possibilities if the multiple output lines are used: e.g., the first line could be used for variable assignments, the second for continuous 'stream of thought', but that's beyond the scope of this post.
该文本输出中的带宽几乎是无限的!如果使用多个输出行,还有更多可能性:例如,第一行可以用于变量赋值,第二行用于连续的“思想流”,但这超出了本文的范围。