我有一些bash函数输出一些信息:
我一直在编写读取输出和过滤它的函数:
function filter-epson {
find-modelname-in-epson-ppds | sed <bla-blah-blah>
}
function filter-hp {
find-modelname-in-hp-ppds | sed <the same bla-blah-blah>
}
etc ...
Run Code Online (Sandbox Code Playgroud)
但我认为最好做这样的事情:
function filter-general {
(somehow get input) | sed <bla-blah-blah>
}
Run Code Online (Sandbox Code Playgroud)
然后调用另一个高级函数:
function high-level-func {
# outputs filtered information
find-modelname-in-hp/epson/...-ppds | filter-general
}
Run Code Online (Sandbox Code Playgroud)
如何通过最好的bash实践实现这一目标?
我在bash脚本中有这个功能,用来创建一个新的jekyll帖子; 但它返回参数作为未找到的命令.这是脚本:
function new_post () {
if [ -z "$1" ]
then
read -p "Post Title:" TITLE
else
TITLE= "$1"
fi
FILE=$( echo $TITLE | tr A-Z a-z | tr ' ' _ )
echo -e '---\nlayout: post\ntitle: '$TITLE'\npublished: false\n---\n' > $(date '+%Y-%m-%d-')"$FILE"'.md'
}
Run Code Online (Sandbox Code Playgroud)
但每当我尝试运行它时,它返回:
$>new_post "Hello World"
-bash: Hello World: command not found
Run Code Online (Sandbox Code Playgroud)
它似乎试图将参数作为命令运行.
我甚至试过这个并得到了相同的结果
$>TITLE= "Hello World" && echo -e ---layout: post\ntitle: "$TITLE"\n---
-bash: Hello World: command not found
Run Code Online (Sandbox Code Playgroud)
谁能告诉我我做错了什么?
该脚本演示了如何使用带括号的括号对话来定义bash函数.括号具有在函数"local"中创建环境变量的良好效果,我想因为函数体作为子shell执行.输出是:
A=something
A=
B=something
B=something
Run Code Online (Sandbox Code Playgroud)
问题是这是否允许定义函数的语法.
#!/bin/bash
foo() (
export A=something
echo A=$A
)
bar() {
export B=something
echo B=$B
}
foo
echo A=$A
bar
echo B=$B
Run Code Online (Sandbox Code Playgroud) 我发现了我的奇怪行为,我无法解释.以下代码工作正常:
function prepare-archive {
blah-blah-blah...
_SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")
exit $?
blah-blah-blah...
}
Run Code Online (Sandbox Code Playgroud)
意味着我得到了我期望的价值:
bash -x ./this-script.sh:
++ exit 1
+ _SPEC_FILE='/home/likern/Print/Oleg/print-service/packaging/print-service.spec
/home/likern/Print/Oleg/print-service/packaging/print-service2.spec'
+ exit 1
Run Code Online (Sandbox Code Playgroud)
只要我local向变量添加定义:
local _SPEC_FILE=$(check-spec-file "$_GIT_DIR/packaging/")
Run Code Online (Sandbox Code Playgroud)
我得到以下:
bash -x ./this-script.sh:
++ exit 1
+ local '_SPEC_FILE=/home/likern/Print/Oleg/print-service/packaging/print-service.spec
/home/likern/Print/Oleg/print-service/packaging/print-service2.spec'
+ exit 0
$:~/MyScripts$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
问题:为什么?发生了什么事?我可以捕获从subshell到local变量的输出并可靠地检查subshell的返回值吗?
PS:prepare-archive在主shell脚本中调用.第一个exit是exitfrom check-spec-file函数,第二个是prepare-archive函数 - 这个函数本身是从main shell脚本执行的.我从返回值check-spec-file的exit 1,那么通过这个值exit $?.因此我希望它们应该是一样的.
我想看看bash函数运行需要多长时间.在做了一点研究之后,我想出了一种使用子shell的方法:
function test-function() {
time (
rsync -av ~/tmp/test-dir-start/ ~/tmp/test-dir-end/
rsync -av ~/tmp/test-dir-start/ ~/tmp/test-dir-end-2/
# etc...
)
}
Run Code Online (Sandbox Code Playgroud)
是否有其他/更好的方法来计时bash功能?
更新:我希望将time调用嵌入到函数中,以便每次都可以运行而无需执行time test-function.我应该更清楚这一点.
我可能在一个bash脚本中有这个函数,它来源于shell
function suman{
echo "using suman function"
}
Run Code Online (Sandbox Code Playgroud)
如果我打电话
unset suman
Run Code Online (Sandbox Code Playgroud)
事情似乎按预期工作
但是,如果我将此作为我的功能:
function suman-inspect {
echo "using suman-inspect function"
}
Run Code Online (Sandbox Code Playgroud)
如果我打电话的话
unset suman-inspect
Run Code Online (Sandbox Code Playgroud)
要么
unset "suman-inspect"
Run Code Online (Sandbox Code Playgroud)
我收到这条消息:
bash: unset: `suman-inspect': not a valid identifier
Run Code Online (Sandbox Code Playgroud)
如何取消设置此变量?
例:
#!/bin/sh
a() {
R=f
ls -1 a*
[ "$?" == "1" ] && { R=t; }
echo $R
}
r=`a`
echo $r
Run Code Online (Sandbox Code Playgroud)
$r包含t或者f也包含ls命令的输出.
我可以写ls -1 a* >/dev/null 2>/dev/null,但如果有一个更复杂的脚本可能导致错误.
有没有办法从单个值返回a()?
我创建了一个简单的秒表(bash函数)来计算时间,但是现在它以毫秒显示当前时间.
代码:
function stopwatch() {
date +%H:%M:%S:%N
while true; do echo -ne "`date +%H:%M:%S:%N`\r"; done;
}
Run Code Online (Sandbox Code Playgroud)
我尝试按照这个答案中的解释改变它,但它仅适用于自Unix Epoch以来的第二个.
当我使用date格式时+%s.%N,由于bash减法只取整数这一事实,上面答案的减法停止了.
如何解决它并有一个终端秒表打印时间如下:
0.000000000
0.123123123
0.435345345
(and so on..)
Run Code Online (Sandbox Code Playgroud)
?
我的bash(4.1) 目录堆栈通常有十几个或更多条目。我想替换dirswith的输出dirs -v,所以我再也不用玩“猜幻数”pushd了。
我替换dirs为dirs -v使用执行的函数command:
dirs()
{
# "command" builtin prevents infinite recusion by suppressing lookup
# of function and alias names.
command dirs -v "${@}"
}
Run Code Online (Sandbox Code Playgroud)
(更新:根据气动学的建议,我现在使用builtin而不是command。它不能解决这个问题,但它稍微安全一些。)
dirs输出现在可读的,但pushd并popd仍产生旧呕吐-的-斜线:
$ pushd ~/just/one/more/and/ill/quit/i/promise
~/just/one/more/and/ill/quit/i/promise ~/tmp/bash/bash-4.1...
may/give/rise/to/dom /oh/no/not/again /var/adm/log /omg/wt...
va/lang ~/doc/comp/java/api/java/util/regex barf barf barf...
Run Code Online (Sandbox Code Playgroud)
dirs用别名替换我的函数后,我得到了相同(缺乏)的结果:
alias dirs='command dirs -v "${@}"'
Run Code Online (Sandbox Code Playgroud)
我终于得到了我想要通过重写输出pushd …
我遇到了一个我认为应该很容易解决的问题,但对于我的生活,我无法弄明白.可能是因为它真的很晚了; 不确定.
所以我有一个shell脚本,我有一个需要运行的if语句.问题是我在这个bash脚本中有一个函数,我用来在if语句中实际构建这个find命令的一部分.我想知道如何在不收到错误的情况下做到这两点[: too many arguments.
这是当前的代码:
if [ -n `find ./ `build_ext_names`` ];then
这就是我真正需要发布的内容.我需要弄清楚如何build_ext_names在find命令中运行,而命令又在if语句中
bash-function ×10
bash ×9
shell ×3
time ×2
built-in ×1
exit-code ×1
if-statement ×1
math ×1
pipe ×1
return-value ×1
sh ×1
timer ×1
unset ×1