
パラメータやパイプから入力を受け取ることができるように、次のbash関数を作成したいと思います。
b64decode() {
echo "$1" | base64 --decode; echo
}
必須使用:
$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQo="
$ b64decode < file.txt
$ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQo="
$ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQo=" | b64decode
答え1
バラよりStefan Chazerasの答えより良い解決策を得るために。
/dev/stdin
以下を使用して標準入力から読み取ることができます。
b64decode()
{
if (( $# == 0 )) ; then
base64 --decode < /dev/stdin
echo
else
base64 --decode <<< "$1"
echo
fi
}
$# == 0
コマンドライン引数が0であることを確認してください。base64 --decode <<< "$1"
使用やパイプのherestring
代わりに使用することも可能です。echo
base64
答え2
ここでは、次のようにする必要があります。
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
。せいぜい(ほとんどのシステムでは)何もせずに(fd 0をfd 0にコピーし、操作なし)と< /dev/stdin
同じことを行います。dup2(0,0)
しかし、LinuxやCygwinでは< /dev/stdin
これは正しく機能しません。これらのシステムでは、オープンは/dev/stdin
stdinのコピーと同じではありません。最初からもう一度開き、現在stdinで開いているファイルと同じファイルを独立して開きます。
したがって、以前にstdinがいくつかの一般的なファイルの途中を指していた場合、後で< /dev/stdin
stdinが現在指している結果が得られます。最初にファイルの。 stdinがパイプの書き込み終了(通常の状況ではあってはいけません)の場合、最終的には読み取り終了になります。ソケットの場合、ソケットは不可能なので失敗します。開いている。読み取り用にファイルを開く権限がない場合も同様です(たとえば、権限が変更されたか、ファイルが元々別の資格情報を使用してstdinで開かれたため)。
戻り値は、base64 --decode < /dev/stdin
ファイル内のstdinの現在の場所(検索可能なファイル入力の場合)は、最後(またはbase64
読み取りが停止する場所)に残っておらず、変更されていません。なぜならbase64
の stdin が別の位置にあるからです。ファイル説明を開く。
答え3
サンディップの答えbase64
これは、ユーティリティが複数行をサポートしていないために機能します。より一般的なケースに対するより一般的な修正
- 複数のコマンドライン引数を受け入れるターゲットユーティリティ
- 複数行を含むパイプまたはリダイレクト
そうですか?
my_function() {
if (( ${#} == 0 )) ; then
while read -r line ; do
target_utility "${line}"
done
else
target_utility "${@}"
fi
}
答え4
両方サンディップそしてトム・ローチ答えは啓発的で感謝していますが、target_utility "${@}"
状況に応じてより複雑なコードを表すことができます。if
重要なコードを内部および外部に複製すると、else
不要な問題が発生する可能性があります。 OPの質問は再帰を使用して完全に解決される問題を提示できないかもしれませんが、他の読者の質問はそれを使用するか、ラッパー機能を使用することを考慮すると役に立ちます。
my_function() {
if (( ${#} == 0 )) ; then
while read -r __my_function ; do
my_function "${__my_function}"
done
else
target_utility "${@}"
fi
}
この回答は、「引数またはパイプの入力を可能にする Bash 関数」に可能なさまざまなソリューションの 1 つです。 OPは[コメントから]これがbase64
実際の問題ドメインではないと指摘したからです。したがって、ファイルから直接入力を読み取ることができることを確認しようとしません。
さまざまな意見によれば、これらのテンプレートと同様のその他のテンプレートは、先行するスペースを含む行を正しく処理できない可能性がありIFS =
ますread
。実際にシェルに機密文字がある場合は、この関数を呼び出す前に特別な処理が必要になる場合があります。現状のまま、コードは先行スペースが発生しないことが知られており、データの感度がエミッタによって前処理されている場合はうまく機能します。
これは単なる教科書の例ではありません。実際の制作スクリプトで使用されます。 target_utility
実際のコードスニペットの簡単な名前です。この回答はユニバーサルテンプレートを想定せず、追加の開発者の知恵を必要としません。
(ユーザーは通常、回答をそのまま使用するのではなく、時々回答を調整すると仮定するのが合理的に見えます。)