
dash
私はdebianstretchで実行しており、次のコマンド(および)はすべてbash
bashに入力されます。決してユーザーとして実行されない
ようですwhoami
テスト以下のコードのようにダッシュで表示されます。
$ sudo dash << 'end'
> su test
> whoami
> end
root
$ sudo bash << 'end'
> su test
> whoami
> end
test
答え1
次の例を考えてみましょう。
$ cat f
grep pos /proc/self/fdinfo/0
IFS= read -r var
echo A
echo B
printf '%s\n' "var=$var"
$ bash < f
pos: 29
B
var=echo A
$ dash < f
pos: 85
A
B
var=
ご覧のとおり、コマンドを実行すると、stdinの場所はファイルgrep
の終わりで、dash
コマンドの後に続く改行文字の直後にあります。grep
bash
コマンドecho A
はによって実行されますが、dash
その場合bash
は入力として与えられますread
。
dash
コマンドを実行する前に、入力全体(実際にはテキストブロック)を一度に1行ずつ読みます。bash
これを行うには、bash
改行文字を通過しないように一度に1バイトずつ読み込む必要がありますが、入力が通常のファイルである場合(上記のファイルの場合と同じでドキュメントにも適用されf
ます)、ここでbashはパイプのdash
使用中に一時ファイルにします。実装します。 Linuxでわかるbash
ように、チャンクで読んで行末に逆追跡して最適化します。strace
$ strace -e読み取り、lseek bash < f [...] lseek(0, 0, SEEK_CUR) = 0 読み取り (0, "grep pos /proc/self/fdinfo/0\nIFS"...,85) = 85 lseek(0, -56, SEEK_CUR) = 29 ポジション:29 [...] $strace -e 読み込み、lseek ダッシュ < f 読み取り (0, "grep pos /proc/self/fdinfo/0\nIFS"...,8192) = 85 ポジション:85 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12422, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- 読み取り(0,"",1) = 0 [...]
stdinがターミナルデバイスの場合、それぞれはread()
ターミナルから送信された行を返すため、通常とbash
同様の動作を見ることができますdash
。
あなたの場合は、次のようにすることができます。
sudo dash << 'end-of-script'
su test <<"end"
whoami
end
end-of-script
またはより良い:
sudo sh -c '
su test -c whoami
'
または、より良い方法は次のとおりです。
sudo -u test whoami
答え2
BashとDashはstdinの入力を異なる方法で扱います。コマンドを実行するとき(su
ここでは)、Bashはコマンドを実行させた後のstdinのタイムセクションパイプで1つの単語を読み取るか、逆に見て読み取る位置を慎重に保ちます。入力がファイルから来ていることを確認してください。ダッシュは気にせず、ブロック全体を読みます。
これは、標準入力とその中の読み取り位置がシェルとサブプロセスとの間で共有されるため、重要です。
したがって、Bashを使用するときを読み、su test\nwhoami\n
最初の改行の後に戻って始めます。su
これがwhoami\n
入力に表示されます。
Dashの場合は、読み込みをsu test\nwhoami\n
開始しsu
、入力が表示されずに終了し、Dashが開始されますwhoami
。
ここでも同じことがわかります。 Dashを使用するとdate
コマンドを実行し、空のread
入力を取得しますが、Bashを使用すると行はread
ですx
。
$ cat test.sh
read x
date
echo "variable x = '$x'"
$ cat test.sh | bash
variable x = 'date'
$ cat test.sh | dash
Sat Aug 24 12:25:23 EEST 2019
variable x = ''
説明するとPOSIXの説明sh
Bashの慎重な行動が必要であることは正しいです。一方、ダッシュの余裕のあるアプローチはこれには適していません。
STDIN
[...]シェルが標準入力を使用し、標準入力も使用するコマンドを呼び出す場合、シェルはコマンドが実行を開始したときに標準入力ファイルポインタが読み取っているコマンドの直後を指すことを確認する必要があります。呼び出されたコマンドで読み取る文字がシェルで消費されるように事前に読み取ってはいけません。
それほど価値があるほど、BusyboxのシェルはDashと同様に機能し、私がテストした他のすべてのシェルはBashの機能を果たします。