假设我有以下 JavaScript:
const something = doSomething();
function doSomething() {
console.log("About to do something");
const a = doSomethingElse();
if (a == "dog") {
console.log("Worked");
console.log("Now let's do xyz");
return "cat";
} else {
console.log("failed for some reason");
return "horse";
}
}
function doSomethingElse() {
console.log("About to do more");
console.log("Done doing more stuff");
return "dog";
}
我们如何在 bash 中实现这一目标?我想实时查看日志,而不是将它们存储在文件中供以后使用?我正在考虑类似以下的内容,但随后所有内容都混合在一起,再加上 bash 中的 return 关键字有其他用途并且不能接受字符串。
something=$(doSomething);
function doSomething() {
console_log "About to do something";
a=$(doSomethingElse);
if [[$a = "dog"]]; then
console_log "Worked";
console_log "Now let's do xyz";
echo "cat"; # Wish I could do return "cat" ...
else
console_log "failed for some reason";
echo "horse"; # Wish I could do return "horse" ...
fi;
}
function doSomethingElse() {
console_log "About to do more";
console_log "Done doing more stuff";
echo 'dog'; #Wish I could do return "dog" ...
}
function console_log() {
#Is echo the right thing, or tee, or something else ?
echo $1;
}
不是有多个输出流来实现这一点吗?或者,是否有 $() 的替代方法来分配变量?我尝试过玩 T 恤、&*、&?和 3>1 的东西,我无法理解这一切......:(
我在 CentOS 7.9 下有 bash 4.2.46
感谢您的帮助 :)
答案1
这应该没问题:
#! /bin/bash -
doSomething() {
print_err "About to do something"
a="$(doSomethingElse)"
if [[ "$a" = "dog" ]]; then
print_err "Worked"
print_err "Now let's do xyz"
printf '%s' "cat"
else
print_err "failed for some reason"
printf '%s' "horse"
fi
}
doSomethingElse() {
print_err "About to do more";
print_err "Done doing more stuff";
printf '%s' 'dog'
}
print_err() {
# Print to stderr as we do this in functions
# that print result to stdout
printf '%s\n' "$1" >&2
}
something="$(doSomething)"
# Making it readonly would be somewhat similar to const
readonly something
printf '%s\n' "$something"
需要:
something="$(doSomething)"
声明后移动doSomething
。 Bash 在读取的基础上执行语句。 (为什么您也可以使用它exit
来中止脚本。)在 JavaScript 中,代码被读取、编译和运行。- 在您的
if test
括号和参数之间需要空格。
一般来说: Bash 运算符 [[ vs [ vs ( vs ((? - 您必须将非数据重定向到
stderr
echo,否则>&2
所有输出都会分配给变量,例如a
.
2>&-、2>/dev/null、|&、&>/dev/null 和 >/dev/null 2>&1 之间的区别
shell 的控制和重定向运算符是什么?
一般来说:
printf
:为什么 printf 比 echo 更好?- 引用。总是引用。最好是经常引用一次,而不是很少引用。https://unix.stackexchange.com/a/68748/140633
function
不需要:https://stackoverflow.com/q/7917018/3342816,bash 中的 grom() 关键字抛出意外的“(”标记
除此之外,替换[[
为[
将使其sh
符合要求。“sh 兼容”是什么意思?
还要查看变量的范围。有没有办法让本地命令可移植到 dash ksh bash 和 zsh?
就像在,你可以有, 完毕:
set_something() {
something='cat'
}
set_something
printf 'something="%s"\n' "$something"
流
JavaScript 不能处理流,而 shell 可以。简化一下:
read
fromstdin
,文件描述符0
(标准)write
tostdout
,文件描述符1
(标准输出)write
tostderr
,文件描述符2
(标准错误)
除此之外,还可以打开新文件、读/写文件等。
可能感兴趣/dev/stdin、/dev/stdout 和 /dev/stderr 的可移植性如何?
返回值。
Bash 函数不会“返回”字符串。当一个人这样做时:
foo="$(some command)"
some command
将的标准输出分配给foo
。如果不更改重定向非数据在您的代码中打印,您可以通过以下方式查看:
# In doSomething():
printf 'a="%s"\n' "$a" >&2
# At end:
printf '"%s"\n' "$something"
你会得到:
a="About to do more
Done doing more stuff
dog"
something="About to do something
failed for some reason
horse"
如您所见,整个输出都已分配。
后“使固定”一可以通过将 stderr 重定向到 stdout 来捕获两者stdout
:stderr
foo="$(some command 2>&1)"
退出代码
然而,Shell 函数确实有退出代码,就像任何程序一样。如果没有显式返回值,则它是该函数中执行的最后一个命令的退出状态。0
没问题,其他任何事情都被认为是测试中的错误。
简单的例子:
#! /bin/bash -
foo() {
printf 'I am foo\n'
return 1
}
greetings() {
if [ "$1" = "hi" ]; then
printf 'Hello\n'
else
printf 'I do not know what to do with %s\n' "$1"
return 12
fi
}
if foo; then
printf 'OK\n'
else
printf 'FAIL\n'
fi
printf '\n## Try greetings "yo":\n'
greetings yo
ecode=$?
printf 'greetings() returned %d\n' "$ecode"
printf '\n## Try greetings "hi":\n'
greetings hi
ecode=$?
printf 'greetings() returned %d\n' "$ecode"
结果:
I am foo
FAIL
## Try greetings "yo":
I do not know what to do with yo
greetings() returned 12
## Try greetings "hi":
Hello
greetings() returned 0
一些帮助shellcheck
虽然不是万无一失,但对检查脚本有很大帮助。
您可以将它用作命令行工具,在线粘贴代码,或将其合并到您的编辑器中。
例如,如果您将 Vim 与 ALE 一起使用,则shellcheck
如果已安装,它就会启动。但请注意,与发行版捆绑在一起的软件包可能有些过时。以Ubuntu 18.04为例,使用v0.4.6
https://github.com/koalaman/shellcheck
一般 Shell 脚本
和等人一起玩bash
。对学习有用。永远考虑你想做什么。例如,使用其他工具进行文本处理几乎总是效果更好。然后可以使用 shell 脚本将它们粘合在一起。使用管道等 - unices 的一部分功能。这里例如sort
,,,,,,,,,,,,,,,,,,,,,,,,等等。join
cut
tr
paste
uniq
find
grep
cat
date
tail
head
xargs
wc
fold
column
paste
交互式 shell 脚本不仅可以使用它,还可以使用各种功能扩展您的 shell。
对于更高级的数据类型和复杂性,可以使用perl
、python
、 以及其他各种类型,甚至c
.c
一般来说,这是一种在较低级别了解系统的非常好的方法。
awk
等sed
对于处理文本也非常强大和有用,更awk
容易学习。