子shell如何在變數(而不是文件)中返回數據並同時輸出不同的日誌?
假設我有以下 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; }
是不是有多個輸出流來實現這一點?或者,是否有替代 $() 來分配變數?我試過玩 tee, &*, &? 和 3>1 的東西,我無法理解這一切…… :(
我在 CentOS 7.9 下有 bash 4.2.46
感謝您的幫助 :)
這應該沒問題:
#! /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
on 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 不適用於流,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
不是萬無一失的,但對 linting 腳本有很大幫助。
您可以將其用作命令行工具、線上粘貼程式碼或將其合併到您的編輯器中。
例如,如果您將 Vim 與 ALE 一起使用,它會
shellcheck
在安裝後繼續執行。請注意,儘管與發行版捆綁在一起的軟體包可能有些過時。例如,Ubuntu 18.04 使用 v0.4.6https://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
更容易學習的文本也非常強大和有用。