次の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 の違い
シェルの制御およびリダイレクト演算子は何ですか?
一般的に言うと:
printf
:なぜprintfがechoより優れているのですか?- 引用する常に引用されます。まれに引用するよりも頻繁に一度引用することをお勧めします。https://unix.stackexchange.com/a/68748/140633
function
不要:https://stackoverflow.com/q/7917018/3342816、Bash の grom() キーワードが予期しない「(」表示を発生させます。
それ以外の場合は、[[
交換すると仕様[
が適用されますsh
。「sh互換」とはどういう意味ですか?
また、変数の範囲を見てください。ksh bashとzshをダッシュするためにデフォルトのコマンドを移植する方法はありますか?
あなたのようにすることができます、完成した:
set_something() {
something='cat'
}
set_something
printf 'something="%s"\n' "$something"
流れ
JavaScriptはストリームを処理できませんが、シェルは処理できます。単純化するには:
read
fromstdin
, ファイル記述子0
(標準)write
stdout
、ファイル記述子(1
標準出力)write
stderr
、ファイル記述子(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)"
終了コード
ただし、シェル関数には他のプログラムと同様に終了コードがあります。明示的な戻り値がない場合は、関数内で実行された最後のコマンドの終了状態です。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
完璧ではありませんが、スクリプトを確認するのに多くの役に立ちます。
コマンドラインツールとして使用できます。オンラインでコードを貼り付ける、またはエディタに統合します。
たとえば、ALE で Vim を使用している場合、shellcheck
Vim がインストールされている場合に起動します。ただし、ディストリビューションにバンドルされているパッケージは多少古いかもしれません。 Ubuntu 18.04を例にとると、v0.4.6を使用してください。
https://github.com/koalaman/shellcheck
一般的なシェルスクリプト
他の人と一緒にプレイしてくださいbash
。学習に便利です。いつもやりたいことを考えてください。たとえば、テキスト処理には他のツールを使用することがほぼ常に優れています。その後、シェルスクリプトを使用して互いに貼り付けることができます。パイプなどを使用してください - unices機能の一部です。ここでは、たとえば、、、、、、、、、、、、、、、、、、、、、、、、、sort
などです。join
cut
tr
paste
uniq
find
grep
cat
date
tail
head
xargs
wc
fold
column
paste
インタラクティブシェルスクリプトはそれを使用できるだけでなく、さまざまな機能でシェルを拡張できます。
perl
より高度なデータ型と複雑さのために、、および他のさまざまな種類python
を使用できます。通常、これは低レベルでシステムを理解するのに非常に良い方法です。c
c
awk
背中はsed
また、テキスト操作に非常に強力で有用であり、awk
学習するのも簡単です。