GNU/Linux >> Znalost Linux >  >> Linux

Proč dokument Parent Shell Here nefunguje pro dílčí příkaz v Dash, ale funguje Bash?

Používám debian stretch, všechny níže uvedené příkazy (dash a bash ) je vstupem do bash.
whoami Zdá se, že se nikdy nespustí jako uživatel test v pomlčce jako v níže uvedených kódech.

$ sudo dash << 'end'
> su test
> whoami
> end
root
$ sudo bash << 'end'
> su test
> whoami
> end
test

Přijatá odpověď:

Zvažte místo toho tento příklad:

$ 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=

Jak můžete vidět, v té době grep Pokud je příkaz spuštěn, pozice v stdin je na konci souboru s dash a hned za nový řádek, který následuje za grep příkaz v bash .

echo A příkaz je spuštěn pomocí dash ale v případě bash , je přiváděn jako vstup pro read .

Stalo se to dash číst celý vstup (ve skutečnosti blok textu), zatímco bash číst jeden řádek po druhém před spuštěním příkazů.

Chcete-li to provést, bash bude muset číst jeden bajt po druhém, aby se ujistil, že nečte za nový řádek, ale když je vstupem běžný soubor (jako v případě mého f výše, ale také pro dokumenty zde, které bash implementuje jako dočasné soubory, zatímco dash používá potrubí), bash optimalizuje jej čtením po blocích a vyhledáváním zpět na konec řádku, který můžete vidět pomocí strace v systému 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
[...]

Když je stdin koncové zařízení, každé read() vrací řádky odeslané terminálem, takže v bash obecně vidíte podobné chování a dash .

Ve vašem případě můžete udělat:

sudo dash << 'end-of-script'
su test <<"end"
whoami
end
end-of-script

nebo lépe:

sudo sh -c '
  su test -c whoami
'

nebo ještě lépe:

sudo -u test whoami

Linux
  1. Přizpůsobení prostředí Bash

  2. Proč nefunguje ~/.bash_profile?

  3. Účel .bashrc a jak to funguje?

  1. Proč není Pgid procesů dítěte PGID rodiče?

  2. Proč substituce procesu Bash nefunguje s některými příkazy?

  3. Odůvodnění Bash Shell vás nevaruje před aritmetickým přetečením atd.?

  1. Proč překladový soubor Bash neobsahuje všechny chybové texty?

  2. Linux – Proč Locale Es_mx funguje, ale Es ne?

  3. Proč „zip“ v A For Loop funguje, když soubor existuje, ale ne, když neexistuje?