我知道 shell 脚本只是运行命令,就好像它们是在命令提示符下执行的一样。我希望能够像运行函数一样运行 shell 脚本......也就是说,将输入值或字符串带入脚本中。我该如何处理?
我用了将近 10 年的 Linux 才问出这个问题。这都是反复试验和随机深夜上网。
但是人们不应该为此需要10年。如果我刚开始使用 Linux,我想知道:何时使用别名、何时编写脚本以及何时编写函数?
就别名而言,我将别名用于不带参数的非常简单的操作。
alias houston='cd /home/username/.scripts/'
Run Code Online (Sandbox Code Playgroud)
这似乎很明显。但有些人这样做:
alias command="bash bashscriptname"
Run Code Online (Sandbox Code Playgroud)
(并将其添加到.bashrc
文件中)
这样做有充分的理由吗?我真的很努力,但我真的想不出任何我想要这样做的情况。因此,如果存在会产生影响的边缘情况,请在下面回答。
因为那是我将一些东西放入我的 PATH 和chmod +x
它的地方,这是经过多年 Linux 反复试验后出现的另一件事。
这让我进入下一个话题。例如,我.scripts/
通过在我的.bashrc
( PATH=$PATH:/home/username/.scripts/
) 中添加一行,在主目录中添加了一个隐藏文件夹 ( ) 到我的 PATH ,因此那里的任何可执行文件都会自动自动完成。
如果我需要的话。
不过,我真的不需要那个,不是吗?我只会将它用于不是 shell 的语言,比如 Python。
如果是 shell,我可以在里面写一个函数.bashrc
:
funcname () {
somecommand -someARGS "$@"
}
Run Code Online (Sandbox Code Playgroud)
正如我所说,我通过反复试验发现了很多。只有当我的电脑没电了,我才真正看到了功能之美,我不得不在周围人不使用它们的时候使用它们。
我没有将整个脚本目录从计算机移动到计算机,而是将其他人的 .bashrc 替换为我自己的,因为他们甚至从未进行过任何修改。
但我错过了什么吗?
那么,关于何时使用别名、何时编写脚本以及何时编写函数,您会告诉 Linux 初学者什么?
如果这不明显,我假设回答这个问题的人会使用所有三个选项。如果你只使用别名,或者只使用脚本,或者只使用函数——或者如果你只使用别名和脚本或别名和函数或脚本和函数——这个问题并不是真正针对你的。
source some_file
Run Code Online (Sandbox Code Playgroud)
some_file:
doit ()
{
echo doit $1
}
export TEST=true
Run Code Online (Sandbox Code Playgroud)
如果我获取 some_file函数“ doit ”和变量 TEST 在命令行上可用。但是运行这个脚本:
脚本.sh:
#/bin/sh
echo $TEST
doit test2
Run Code Online (Sandbox Code Playgroud)
将返回 TEST 的值,但会产生关于未知函数“doit”的错误。
我也可以“导出”该函数,还是必须在 script.sh 中获取 some_file 才能在那里使用该函数?
我可以bash
使用或省略function
关键字来定义函数。有什么区别吗?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Run Code Online (Sandbox Code Playgroud)
这两个函数调用foo
和bar
成功,我看不出有什么区别。所以我想知道它是否只是为了提高可读性,或者我遗漏了什么......
顺便说一句,在其他 shell 中,例如dash
(在 debian/ubuntu 中/bin/sh
符号链接dash
)它在使用function
关键字时失败。
在工作中,我经常编写 bash 脚本。我的主管建议将整个脚本分解为函数,类似于以下示例:
#!/bin/bash
# Configure variables
declare_variables() {
noun=geese
count=three
}
# Announce something
i_am_foo() {
echo "I am foo"
sleep 0.5
echo "hear me roar!"
}
# Tell a joke
walk_into_bar() {
echo "So these ${count} ${noun} walk into a bar..."
}
# Emulate a pendulum clock for a bit
do_baz() {
for i in {1..6}; do
expr $i % 2 >/dev/null && echo "tick" || echo "tock"
sleep 1
done
}
# Establish run order
main() { …
Run Code Online (Sandbox Code Playgroud) 当我在.bash_aliases
文件中定义一个新别名或在文件中定义一个新函数时.bashrc
,是否有一些刷新命令能够立即使用新别名或函数而无需关闭终端(在我的情况下,xfce4-terminal 打开了几个选项卡,打开了许多文件并且在工作中)?
Linux 中以下退出代码的最小值和最大值是多少:
exit
)。return
)。我认为这是介于0
和之间255
。阅读24.2 后。局部变量,我认为var
用关键字声明一个变量local
意味着它var
的值只能在由函数大括号分隔的代码块内访问。
但是,在运行以下示例后,我发现var
也可以从该代码块调用的函数中访问、读取和写入 - 即即使var
声明local
为outerFunc
,innerFunc
仍然能够读取它并更改其值。
#!/usr/bin/env bash
function innerFunc() {
var='new value'
echo "innerFunc: [var:${var}]"
}
function outerFunc() {
local var='initial value'
echo "outerFunc: before innerFunc: [var:${var}]"
innerFunc
echo "outerFunc: after innerFunc: [var:${var}]"
}
echo "global: before outerFunc: [var:${var}]"
outerFunc
echo "global: after outerFunc: [var:${var}]"
Run Code Online (Sandbox Code Playgroud)
输出:
global: before outerFunc: [var:] # as expected, `var` is not accessible outside of …
Run Code Online (Sandbox Code Playgroud) 这个站点说:“Shell 函数 [比别名] 更快。在函数之后查找别名,因此解析速度较慢。虽然别名更容易理解,但几乎在所有用途中,shell 函数都比别名更受欢迎。”
鉴于此(对与否),shell 函数与独立的 shell 脚本相比如何?一个比另一个有特别的优势,还是更适合某些类型的任务?
我在 Solaris 10 上使用 ksh (88)、bash (3.00) 和 zsh (4.2.1) 测试了以下内容。
以下代码不会产生任何结果:
function foo {
echo "Hello World"
}
find somedir -exec foo \;
Run Code Online (Sandbox Code Playgroud)
这一发现不匹配多个文件(如更换-exec ...
用-print
),并从外面叫时功能完美的作品find
调用。
以下是该man find
页面的内容-exec
:
-exec command 如果执行的命令返回一个,则为真 零值作为退出状态。结尾 命令必须以转义字符作为标点 分号 (;)。命令参数 {} 是 替换为当前路径名。如果 -exec 的最后一个参数是 {} 而你 指定 + 而不是分号 (;), 命令被调用的次数更少, {} 替换为路径名组。如果 命令的任何调用都会返回一个 非零值作为退出状态,找到 返回非零退出状态。
我可能会做这样的事情:
for f in $(find somedir); do
foo
done
Run Code Online (Sandbox Code Playgroud)
但我害怕处理字段分隔符问题。
是否可以从调用中调用 shell 函数(在同一个脚本中定义,让我们不要理会范围问题)find ... -exec ...
? …
function ×10
bash ×7
shell-script ×5
alias ×3
shell ×3
bashrc ×1
command-line ×1
executable ×1
exit-status ×1
find ×1
ksh ×1
linux ×1
posix ×1
solaris ×1
terminal ×1
variable ×1