Sono eseguito su debian stretch, tutti sotto i comandi (dash
e bash
) viene inserito in bash.
Il whoami
sembra non essere mai eseguito come test dell'utente in trattino come nei codici sottostanti.
$ sudo dash << 'end'
> su test
> whoami
> end
root
$ sudo bash << 'end'
> su test
> whoami
> end
test
Risposta accettata:
Considera invece questo esempio:
$ 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=
Come puoi vedere, al momento il grep
viene eseguito, la posizione all'interno di stdin è alla fine del file con dash
, e subito dopo la nuova riga che segue grep
comando in bash
.
Il echo A
il comando è eseguito da dash
ma nel caso di bash
, viene alimentato come input per read
.
Quello che è successo è quel dash
leggi l'intero input (in realtà, un blocco di testo) mentre bash
leggere una riga alla volta prima di eseguire i comandi.
Per farlo, bash
dovrebbe leggere un byte alla volta per assicurarsi che non legga oltre la nuova riga, ma quando l'input è un file normale (come nel caso del mio f
file sopra, ma anche per here-documenti che bash implementa come file temporanei, mentre dash
utilizza pipe), bash
lo ottimizza leggendo per blocchi e tornando alla fine della riga, che puoi vedere con strace
su Linux:
$ strace -e read,lseek bash < f [...] lseek(0, 0, SEEK_CUR) = 0 read(0, "grep pos /proc/self/fdinfo/0\nIFS"..., 85) = 85 lseek(0, -56, SEEK_CUR) = 29 pos: 29 [...] $ strace -e read,lseek dash < f read(0, "grep pos /proc/self/fdinfo/0\nIFS"..., 8192) = 85 pos: 85 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12422, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- read(0, "", 1) = 0 [...]
Quando stdin è un dispositivo terminale, ogni read()
restituisce le righe come inviate dal terminale, quindi generalmente vedi un comportamento simile in bash
e dash
.
Nel tuo caso potresti fare:
sudo dash << 'end-of-script'
su test <<"end"
whoami
end
end-of-script
o meglio:
sudo sh -c '
su test -c whoami
'
o meglio ancora:
sudo -u test whoami