Cambia temporaneamente / bin / sh link


9

Ho un software che richiede /bin/shdi essere Bash, ma per Ubuntu il valore predefinito è Dash e voglio mantenerlo predefinito; Non voglio cambiarlo permanentemente in Bash.

C'è un modo per cambiarlo solo per una sessione terminale in esecuzione? Quindi un programma in esecuzione in questo terminale vedrà /bin/shcollegato a bash ma il resto del sistema vedrà ancora Dash? O posso ingannare il software per vedere /bin/shcome Bash anche se non lo è?

Non ho scritto questo software e l'hacking da usare al /bin/bashposto di /bin/shnon è davvero un'opzione.


2
È possibile modificarlo temporaneamente - ma non (AFAIK) limitare l'ambito a una singola sessione terminale. Vedi ad esempio / bin / sh è un collegamento simbolico che non punta a / bin / bash
steeldriver


7
Qualunque cosa tu faccia, ti preghiamo di segnalarlo anche come bug per il software in questione. Perché assumendo /bin/shè bash è un bug, e che provoca problemi reali (come si sta trovando fuori). Se nessuno si lamenta, potrebbe non essere mai cambiato.
marcelm,

1
@SergiyKolodyazhnyy Se il bug non causa problemi sulle sole piattaforme supportate, probabilmente possono cavarsela. È comunque un bug.
marzo

1
Il software è Petalinux rilasciato da una "piccola" compagnia chiamata Xilinx e secondo la documentazione Ubuntu 16.04 è supportato (insieme a CentOS e RHEL), quindi direi che è un bug.
corwin,

Risposte:


10

Due risposte suggeriscono già chrooting e bind mount, e c'è una terza opzione strettamente correlata: mount namespace . Utilizzando il unshareprogramma , è possibile creare un nuovo spazio dei nomi di montaggio e i montaggi all'interno di questo spazio dei nomi non influiranno su altri spazi dei nomi.

Ad esempio, in un terminale, faccio:

muru|[0] ~ sudo unshare -m /bin/bash
root@muru-1604:~# sudo mount --bind /bin/bash /bin/sh
root@muru-1604:~# /bin/sh --version
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@muru-1604:~# sudo -iu muru
muru|[0] ~ /bin/sh --version  # propagates
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

E in un altro:

$ /bin/sh --version
/bin/sh: 0: Illegal option --

Quindi potresti eseguire questo programma inflessibile nel suo spazio dei nomi mount.


14

Se è uno script, basta chiamare lo script come

bash scriptname.sh

Non è necessario modificare i collegamenti.

Per l'eseguibile compilato puoi andare chroot route:

mkdir rootfs
cp -a /usr rootfs/
cp -a /lib rootfs/
cp -a /lib64 rootfs/
cp /bin/bash  rootfs/bin/sh
cp yourprogram  rootfs/
sudo chroot rootfs  sh

E quindi eseguire il programma o sudo chroot rootfs /yourprogram


Tuttavia, in pratica non vi è alcun motivo per cui non è possibile utilizzare /bin/bashcome link simbolico a /bin/sh. In effetti, prima della versione 6.10 Ubuntu utilizzava /bin/bashas /bin/sh, e poi sono passati a causa di /bin/shun'implementazione molto più veloce e più snella di POSIX /bin/sh(ovvero, aderisce allo standard POSIX per come le utility del sistema operativo e il sistema operativo simili a Unix dovrebbero comportarsi e implementare alcuni dei loro interni), e per motivi di portabilità. Consiglio vivamente di leggere la risposta di Gilles anche per le note storiche su come /bin/dashè successo . Per quanto riguarda la compatibilità, gli script scritti per l' dashutilizzo delle funzionalità POSIX verranno eseguiti con bashuna shell predefinita perfettamente funzionante. Di solito, è il contrario che causa problemi -bashha funzionalità che non sono richieste da /bin/sh, come la <<<sintassi o le matrici.

Inoltre, il comando in questione è probabilmente scritto pensando a RHEL o CentOS, che utilizza /bin/bashcome link simbolico /bin/sh, suggerisce due cose: probabilmente hanno preso di mira specifici sistemi operativi e non hanno aderito ai principi POSIX. In tal caso, sarebbe anche una buona idea controllare quali altre cose il comando richiede, poiché se è davvero scritto con un altro sistema operativo in mente, potresti riscontrare più problemi del semplice ricollegamento /bin/sh.


2
LOL. La vita può essere così semplice :-)
PerlDuck,

1
Hai guadagnato il mio voto :)
Joshua Besneatte,

@JoshuaBesneatte Grazie! Sono contento che trovi utile la mia risposta
Sergiy Kolodyazhnyy,

3
+1 e potrebbe essere meglio creare collegamenti reali anziché copie (tramite lno cp -l).
David Foerster,

1
Considerare mount --rbind --make-rslavepiuttosto che cp -r. Può essere anche di sola lettura. sudo chrootEsegue anche lo script come root che potrebbe non essere ottimale.
Roman Odaisky,

5

Una possibilità potrebbe essere un mount bind di un singolo file. Per fare questo, monti il file /bin/bashappena sopra /bin/dash così una bashsorta di copertine o nascondigli dash. Ecco i passaggi (incluso il contrario):

root@myhost:~# cd /bin

# situation before (bash and dash are different):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# mount /bin/bash over /bin/dash:
root@myhost:/bin# mount --bind /bin/bash /bin/dash

# situation now (bash and dash are the same):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# Now everything that runs `/bin/sh` in fact uses `/bin/bash`.

# check what the symlink "sh" says:
root@myhost:/bin# sh --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
...

# undo the mount:
root@myhost:/bin# umount /bin/dash 

# situation now (bash and dash are different again):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# check what the symlink "sh" now says:
root@myhost:/bin# sh --version
sh: 0: Illegal option --

Tuttavia, non ho provato a nasconderemount --bind /bin/bash /bin/sh direttamente il collegamento simbolico. Il trucco di cui sopra rende bash e dash identici, quindi fa riferimento anche se punta a . Inoltre, questa è una soluzione a livello di sistema, non solo per la finestra del terminale corrente.mountshbashdash


Devo confessare, questo potrebbe essere eccessivo e semplicemente cambiare temporaneamente il link simbolico è molto più facile. Volevo solo mostrare un altro modo possibile.


1

Dovresti essere in grado di cambiarlo solo per la sessione corrente usando un alias. Prima di eseguire il comando nel terminale:

alias sh=bash

Questo sarà temporaneo e attivo solo nel terminale da cui è stato eseguito.

TUTTAVIA: NON funzionerà se lo script utilizza percorsi assoluti.

Buona idea in quanto tale, ma se il software chiama direttamente / bin / sh con un percorso esplicito, non funzionerà. Ad ogni modo, quel software non sembra essere progettato in modo molto appropriato facendo simili ipotesi. Probabilmente l'avrei eseguito da uno script che prepara e ripristina l'ambiente corretto se dovessi usarlo affatto. - vanadio

Sfortunatamente, "l'hacking" dello script potrebbe essere la tua unica opzione. Per convo con @vanadium, è possibile creare uno script wrapper come questo:

#!/bin/bash
sudo ln -sf /bin/bash /bin/sh
/run/my/script
sudo ln -sf /bin/dash /bin/sh

Tuttavia, durante la durata dello script, è meglio sperare che nulla sul tuo sistema richieda esplicitamente trattino.


3
Buona idea in quanto tale, ma se il software chiama direttamente / bin / sh con un percorso esplicito, non funzionerà. Ad ogni modo, quel software non sembra essere progettato in modo molto appropriato facendo simili ipotesi. Probabilmente l'avrei eseguito da uno script che prepara e ripristina l'ambiente corretto se dovessi usarlo affatto.
vanadio,

Sarei interessato a vedere come faresti per preparare l'ambiente. useresti chroot?
Joshua Besneatte,

Non avevo idee così ambiziose. Stavo solo pensando a uno script che avrebbe temporaneamente sh link a bash e resettato al termine. Il problema principale in questa domanda riguarda il "software" in questione, credo.
vanadio,

cosa accadrebbe se qualcos'altro avesse bisogno di trattino mentre il collegamento simbolico veniva spostato ... qualcosa come ln -sf / bin / bash / bin / sh all'inizio e ln -sf / bin / dash / bin / sh quando fatto?
Joshua Besneatte,

La maggior parte degli altri processi probabilmente utilizzerà felicemente bash anziché dash se il collegamento viene modificato. Sì, in quel senso, ma per imitare la situazione attuale, creerei collegamenti relativi, ad esempio "cd / bin; ln -sf bash sh", ma è probabilmente un dettaglio purista che non importerà in pratica.
vanadio,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.