Link / bin / sh vorübergehend ändern

9

Ich habe eine Software, die /bin/shBash sein muss, aber für Ubuntu ist der Standard Dash und ich möchte den Standard beibehalten. Ich möchte es nicht dauerhaft in Bash ändern.

Gibt es eine Möglichkeit, dies nur für eine laufende Terminalsitzung zu ändern? Ein Programm, das in diesem Terminal ausgeführt wird, wird also /bin/shmit Bash verknüpft, aber der Rest des Systems wird weiterhin Dash sehen. Oder kann ich die Software austricksen, um sie /bin/shals Bash zu sehen, auch wenn dies nicht der Fall ist?

Ich habe nicht diese Software schreiben und Hacking , es zu benutzen , /bin/bashanstatt /bin/shist nicht wirklich eine Option.

Corwin
quelle
2
Sie können es vorübergehend ändern - aber nicht (AFAIK) den Bereich auf eine einzelne Terminalsitzung beschränken. Siehe zum Beispiel / bin / sh ist ein symbolischer Link, der nicht auf / bin / bash
steeldriver
2
Möglicherweise von Interesse: unix.stackexchange.com/questions/468289/…
ejjl
7
Was auch immer Sie tun, melden Sie dies bitte auch als Fehler für die betreffende Software. Weil die Annahme, dass /bin/shes sich bash um einen Fehler handelt, tatsächliche Probleme verursacht (wie Sie herausfinden). Wenn sich niemand beschwert, wird es möglicherweise nie geändert.
Marcelm
1
@SergiyKolodyazhnyy Wenn der Fehler auf den einzigen Plattformen, die sie unterstützen, keine Probleme verursacht, können sie wahrscheinlich damit durchkommen. Es ist immer noch ein Fehler.
Marcelm
1
Die Software ist Petalinux, veröffentlicht von einer "kleinen" Firma namens Xilinx, und laut Dokumentation wird Ubuntu 16.04 (zusammen mit CentOS und RHEL) unterstützt, daher würde ich sagen, dass es ein Fehler ist.
Corwin

Antworten:

10

Zwei Antworten schlagen bereits vor, Mounts zu chrooten und zu binden, und es gibt eine dritte, eng verwandte Option: Mount-Namespaces . Mit dem unshareProgramm können Sie einen neuen Mount-Namespace erstellen, und Mounts in diesem Namespace wirken sich nicht auf andere Namespaces aus.

Zum Beispiel mache ich in einem Terminal:

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.

Und in einem anderen:

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

Sie können dieses unflexible Programm also in einem eigenen Mount-Namespace ausführen.

muru
quelle
14

Wenn es sich um ein Skript handelt, rufen Sie das Skript einfach als auf

bash scriptname.sh

Links müssen nicht geändert werden.

Für kompilierte ausführbare Dateien können Sie chroot Route gehen:

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

Und dann führen Sie Ihr Programm oder sudo chroot rootfs /yourprogram


In der Praxis gibt es jedoch keinen Grund, warum Sie nicht /bin/bashals Symlink zu verwenden können /bin/sh. Tatsächlich verwendete Ubuntu vor Version 6.10/bin/bash as /bin/shund wechselte dann aufgrund /bin/sheiner viel schnelleren und schlankeren Implementierung von POSIX /bin/sh(dh es entspricht dem POSIX-Standard für das Verhalten von Unix-ähnlichen Betriebssystem-Dienstprogrammen und Betriebssystemen und einige ihrer Interna implementieren) und aus Gründen der Portabilität. Ich empfehle dringend, auch Gilles 'Antwort zu lesen, um historische Notizen darüber zu erhalten, wie es dazu /bin/dashkam. Aus Gründen der Kompatibilität werden Skripte, die für die dashVerwendung von POSIX-Funktionen geschrieben wurden bash, als Standard-Shell ausgeführt. Normalerweise ist es umgekehrt, was Probleme verursacht -bashverfügt über Funktionen, die von nicht benötigt werden /bin/sh, wie die <<<Syntax oder Arrays.

Darüber hinaus wurde der betreffende Befehl wahrscheinlich unter Berücksichtigung von RHEL oder CentOS geschrieben, das /bin/bashals Symlink zu verwendet /bin/shwird. Es schlägt zwei Dinge vor: Sie zielen wahrscheinlich auf ein bestimmtes Betriebssystem ab und haben die POSIX-Prinzipien nicht eingehalten. In diesem Fall ist es auch eine gute Idee, zu überprüfen, welche anderen Dinge der Befehl erfordert, da Sie möglicherweise mehr Probleme haben, als nur eine erneute Verknüpfung vorzunehmen, wenn er wirklich für ein anderes Betriebssystem geschrieben wurde /bin/sh.

Sergiy Kolodyazhnyy
quelle
2
LOL. Das Leben kann so einfach sein :-)
PerlDuck
1
Du hast meine Gegenstimme verdient :)
Joshua Besneatte
@ JoshuaBesneatte Danke! Ich
bin
3
+1 und es ist möglicherweise besser, feste Links anstelle von Kopien (über lnoder cp -l) zu erstellen .
David Foerster
1
Betrachten Sie mount --rbind --make-rslaveeher als cp -r. Kann auch schreibgeschützt gemacht werden. Führt sudo chrootdas Skript auch als root aus, was möglicherweise nicht optimal ist.
Roman Odaisky
5

Eine Möglichkeit wäre ein Bind-Mount einer einzelnen Datei. Um dies zu tun, hängen Sie die Datei /bin/bashdirekt über /bin/dash so eine bashArt Cover oder Hides dash. Hier sind die Schritte (einschließlich der Umkehrung):

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

Ich habe jedoch nicht versucht, den Symlink mount --bind /bin/bash /bin/shdirekt auszublenden . Der obige mountTrick macht nur Bash und Dash identisch, so dass er shsich darauf bezieht, bashobwohl er darauf verweist dash. Dies ist auch eine systemweite Lösung, nicht nur für das aktuelle Terminalfenster.


Ich muss gestehen, das könnte übertrieben sein und es ist viel einfacher, den Symlink nur vorübergehend zu ändern. Ich wollte nur einen anderen möglichen Weg zeigen.

PerlDuck
quelle
1

Sie sollten es nur für die aktuelle Sitzung mithilfe eines Alias ​​ändern können. Bevor Sie Ihren Befehl im Terminal ausführen:

alias sh=bash

Dies ist vorübergehend und nur in dem Terminal aktiv, von dem aus es ausgeführt wurde.

JEDOCH: Dies funktioniert NICHT, wenn Ihr Skript absolute Pfade verwendet.

Gute Idee als solche, aber wenn die Software / bin / sh direkt mit einem expliziten Pfadnamen aufruft, funktioniert dies nicht. Wie auch immer, diese Software scheint unter diesen Voraussetzungen nicht sehr richtig entworfen zu sein. Ich würde es wahrscheinlich über ein Skript ausführen, das die richtige Umgebung vorbereitet und zurücksetzt, wenn ich es überhaupt verwenden müsste. - Vanadium

Leider ist das "Hacken" des Skripts möglicherweise Ihre einzige Option. Per Convo mit @vanadium können Sie ein Wrapper-Skript wie folgt erstellen:

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

Während der Dauer Ihres Skripts hoffen Sie jedoch besser, dass nichts auf Ihrem System explizit einen Strich erfordert.

Joshua Besneatte
quelle
3
Gute Idee als solche, aber wenn die Software / bin / sh direkt mit einem expliziten Pfadnamen aufruft, funktioniert dies nicht. Wie auch immer, diese Software scheint unter diesen Voraussetzungen nicht sehr richtig entworfen zu sein. Ich würde es wahrscheinlich über ein Skript ausführen, das die richtige Umgebung vorbereitet und zurücksetzt, wenn ich es überhaupt verwenden müsste.
Vanadium
Es würde mich interessieren, wie Sie die Umwelt vorbereiten würden. Würden Sie Chroot verwenden?
Joshua Besneatte
Ich hatte keine so ehrgeizigen Ideen. Ich dachte nur an ein Skript, das vorübergehend einen Link zu Bash und Reset haben würde, wenn es fertig wäre. Das Hauptproblem bei dieser Frage liegt meiner Meinung nach bei der betreffenden "Software".
Vanadium
Was würde passieren, wenn etwas anderes einen Strich benötigt, während der symbolische Link verschoben wurde? Etwas wie ln -sf / bin / bash / bin / sh am Anfang und ln -sf / bin / dash / bin / sh, wenn fertig?
Joshua Besneatte
Die meisten anderen Prozesse verwenden wahrscheinlich gerne Bash anstelle von Bindestrich, wenn der Link geändert wird. Ja, umsonst, aber um die aktuelle Situation nachzuahmen, würde ich relative Links herstellen, dh "cd / bin; ln -sf bash sh", aber das ist wahrscheinlich ein puristisches Detail, das in der Praxis keine Rolle spielt.
Vanadium