Bash
接受來自參數或管道的輸入的 Bash 函式
我想以一種可以接受來自參數或管道的輸入的方式編寫以下 bash 函式:
b64decode() { echo "$1" | base64 --decode; echo }
所需用途:
$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQo=" $ b64decode < file.txt $ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQo=" $ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQo=" | b64decode
請參閱Stéphane Chazelas 的答案以獲得更好的解決方案。
您可以使用
/dev/stdin
從標準輸入中讀取b64decode() { if (( $# == 0 )) ; then base64 --decode < /dev/stdin echo else base64 --decode <<< "$1" echo fi }
$# == 0
檢查命令行參數的數量是否為零base64 --decode <<< "$1"
也可以使用herestring
而不是使用echo
和管道到base64
這裡應該是:
b64decode() { if [ "$#" -gt 0 ]; then # concatenated arguments fed via a pipe. printf %s "$@" | base64 --decode else base64 --decode # read from stdin fi ret=$? echo # add one newline character return "$ret" # return with base64's exit status to report decoding # errors if any. }
在任何情況下,不要使用
base64 --decode < /dev/stdin
. 充其量(在大多數係統上)< /dev/stdin
什麼都不做,它只是相當於dup2(0,0)
(將 fd 0 複製到 fd 0,無操作)。但是在 Linux 或 Cygwin 上,
< /dev/stdin
這裡不能正常工作。在這些系統上,打開/dev/stdin
不像複製標準輸入,它會從頭開始重新打開,並且與目前在標準輸入上打開的文件相同。因此,如果以前 stdin 指向某個正常文件的中間,那麼在 之後
< /dev/stdin
,您最終會看到 stdin 現在指向該文件的開頭。如果 stdin 是管道的寫入端(在正常情況下不應該這樣做),那麼您最終會成為讀取端。如果它是一個套接字,那麼它將失敗,因為套接字無法打開。如果您無權打開該文件進行讀取,則相同(例如,因為權限已更改或文件最初是使用不同的憑據在標準輸入上打開的)。並且在
base64 --decode < /dev/stdin
返回之後,文件中的標準輸入的目前位置(用於可搜尋的文件輸入)將保持不變,不會留在最後(或base64
停止讀取的地方),因為base64
’s stdin 在不同的打開文件描述中。