Dies muss entweder sehr einfach oder sehr komplex sein, aber ich konnte nichts darüber finden ... Ich versuche, eine neue Bash-Instanz zu öffnen, dann ein paar Befehle darin auszuführen und die Steuerung dem Benutzer darin zurückzugeben gleiche Instanz .
Ich habe es versucht:
$ bash -lic "some_command"
Dies wird jedoch some_command
in der neuen Instanz ausgeführt und dann geschlossen. Ich möchte, dass es offen bleibt.
Ein weiteres Detail, das sich auf die Antworten auswirken könnte: Wenn ich dies zum Laufen bringen kann, verwende ich es in meinem .bashrc
Alias ( meinen Alias), also Bonuspunkte für eine alias
Implementierung!
alias shortcut='bash -lic "some_command"'
in meine .bashrc zu setzen, dann auszuführenshortcut
und eine neue Shell zu haben, in dersome_command
bereits ausgeführt wurde.Antworten:
bash --rcfile <(echo '. ~/.bashrc; some_command')
verzichtet auf die Erstellung temporärer Dateien. Frage auf anderen Seiten:
quelle
The system cannot find the file specified.
cat ~/.bashrc
? 2) Funktioniertcat <(echo a)
? 3) Funktioniertbash --rcfile somefile
?bash.exe --rcfile ^<^(echo 'source $HOME/.bashrc; ls; pwd'^)
sollte über die Windows-Eingabeaufforderung ausgeführt werden.sudo bash --init-file <(echo "ls; pwd")
oder zu machensudo -iu username bash --init-file <(echo "ls; pwd")
?Dies ist eine späte Antwort, aber ich hatte genau das gleiche Problem und Google hat mich auf diese Seite geschickt. Der Vollständigkeit halber habe ich hier das Problem umgangen.
Soweit ich das beurteilen kann,
bash
gibt es keine Möglichkeit, das zu tun, was das Originalplakat wollte. Die-c
Option wird immer zurückgegeben, nachdem die Befehle ausgeführt wurden.Defekte Lösung : Der einfachste und offensichtlichste Versuch, dies zu umgehen, ist:
bash -c 'XXXX ; bash'
Dies funktioniert teilweise (wenn auch mit einer zusätzlichen Unterschalenschicht). Das Problem ist jedoch, dass während eine Sub-Shell die exportierten Umgebungsvariablen erbt, Aliase und Funktionen nicht geerbt werden. Dies könnte für einige Dinge funktionieren, ist jedoch keine allgemeine Lösung.
Besser : Um dies zu umgehen, erstellen Sie dynamisch eine Startdatei und rufen bash mit dieser neuen Initialisierungsdatei auf. Stellen Sie dabei sicher, dass Ihre neue Init-Datei
~/.bashrc
bei Bedarf Ihre reguläre Datei aufruft .# Create a temporary file TMPFILE=$(mktemp) # Add stuff to the temporary file echo "source ~/.bashrc" > $TMPFILE echo "<other commands>" >> $TMPFILE echo "rm -f $TMPFILE" >> $TMPFILE # Start the new bash shell bash --rcfile $TMPFILE
Das Schöne ist, dass sich die temporäre Init-Datei selbst löscht, sobald sie verwendet wird, wodurch das Risiko verringert wird, dass sie nicht korrekt bereinigt wird.
Hinweis: Ich bin nicht sicher, ob / etc / bashrc normalerweise als Teil einer normalen Nicht-Login-Shell aufgerufen wird. Wenn ja, möchten Sie vielleicht / etc / bashrc sowie Ihre
~/.bashrc
.quelle
rm -f $TMPFILE
Ding macht es. Ich erinnere mich nicht wirklich an den Anwendungsfall, den ich dafür hatte, und ich verwende jetzt fortgeschrittenere Automatisierungstechniken, aber das ist der richtige Weg!bash --rcfile <(echo ". ~/.bashrc; a=b")
trap
.Sie können
--rcfile
an Bash übergeben, um eine Datei Ihrer Wahl zu lesen. Diese Datei wird anstelle Ihrer gelesen.bashrc
. (Wenn das ein Problem ist, beziehen Sie es~/.bashrc
aus dem anderen Skript.)Bearbeiten: Eine Funktion zum Starten einer neuen Shell mit dem Material von
~/.more.sh
würde also ungefähr so aussehen:more() { bash --rcfile ~/.more.sh ; }
... und
.more.sh
Sie hätten die Befehle, die Sie ausführen möchten, wenn die Shell startet. (Ich nehme an, es wäre elegant, eine separate Startdatei zu vermeiden. Sie können keine Standardeingabe verwenden, da die Shell dann nicht interaktiv ist. Sie können jedoch eine Startdatei aus einem Dokument hier an einem temporären Speicherort erstellen und dann lesen.)quelle
Sie können die gewünschte Funktionalität erhalten, indem Sie das Skript beziehen, anstatt es auszuführen. z.B:
quelle
alias=''
einzubetten?Fügen Sie
~/.bashrc
einen Abschnitt wie diesen hinzu:if [ "$subshell" = 'true' ] then # commands to execute only on a subshell date fi alias sub='subshell=true bash'
Dann können Sie die Subshell mit starten
sub
.quelle
env subshell=true bash
(da dies nicht$subshell
zu nachfolgenden Befehlen führt): Verwenden von env im Vergleich zum Verwenden von Export .env
. Um zu überprüfen, ob definiert ist oder nicht, verwende ichecho $subshell
(anstelle dessenenv | grep subshell
, was Sie verwenden).Die akzeptierte Antwort ist wirklich hilfreich! Nur um diese Prozesssubstitution (dh
<(COMMAND)
) hinzuzufügen, wird sie in einigen Shells (zdash
. B. ) nicht unterstützt .In meinem Fall habe ich versucht, eine benutzerdefinierte Aktion (im Grunde ein einzeiliges Shell-Skript) im Thunar-Dateimanager zu erstellen, um eine Shell zu starten und die ausgewählte virtuelle Python-Umgebung zu aktivieren. Mein erster Versuch war:
urxvt -e bash --rcfile <(echo ". $HOME/.bashrc; . %f/bin/activate;")
Wo
%f
ist der Pfad zur virtuellen Umgebung, der von Thunar verwaltet wird? Ich habe einen Fehler erhalten (indem ich Thunar über die Befehlszeile ausgeführt habe):/bin/sh: 1: Syntax error: "(" unexpected
Dann wurde mir klar, dass mein
sh
(im Wesentlichendash
) Prozessersatz nicht unterstützt.Meine Lösung bestand darin,
bash
auf oberster Ebene aufzurufen , um die Prozessersetzung auf Kosten einer zusätzlichen Shell-Ebene zu interpretieren:bash -c 'urxvt -e bash --rcfile <(echo "source $HOME/.bashrc; source %f/bin/activate;")'
Alternativ habe ich versucht, hier-Dokument für zu verwenden,
dash
aber ohne Erfolg. Etwas wie:echo -e " <<EOF\n. $HOME/.bashrc; . %f/bin/activate;\nEOF\n" | xargs -0 urxvt -e bash --rcfile
PS: Ich habe nicht genug Ruf, um Kommentare zu posten. Moderatoren können diese gerne in Kommentare verschieben oder entfernen, wenn sie bei dieser Frage nicht hilfreich sind.
quelle
In Übereinstimmung mit der Antwort von daveraja ist hier ein Bash-Skript, das den Zweck lösen wird.
Stellen Sie sich eine Situation vor, wenn Sie C-Shell verwenden und einen Befehl ausführen möchten, ohne den Kontext / das Fenster der C-Shell wie folgt zu verlassen:
Auszuführender Befehl : Suchen Sie das genaue Wort 'Testen' im aktuellen Verzeichnis rekursiv nur in * .h, * .c-Dateien
grep -nrs --color -w --include="*.{h,c}" Testing ./
Lösung 1 : Geben Sie bash von der C-Shell aus ein und führen Sie den Befehl aus
bash grep -nrs --color -w --include="*.{h,c}" Testing ./ exit
Lösung 2 : Schreiben Sie den beabsichtigten Befehl in eine Textdatei und führen Sie ihn mit bash aus
echo 'grep -nrs --color -w --include="*.{h,c}" Testing ./' > tmp_file.txt bash tmp_file.txt
Lösung 3 : Führen Sie den Befehl mit bash in derselben Zeile aus
bash -c 'grep -nrs --color -w --include="*.{h,c}" Testing ./'
Lösung 4 : Erstellen Sie einen sciprt (einmalig) und verwenden Sie ihn für alle zukünftigen Befehle
alias ebash './execute_command_on_bash.sh' ebash grep -nrs --color -w --include="*.{h,c}" Testing ./
Das Skript lautet wie folgt:
#!/bin/bash # ========================================================================= # References: # https://stackoverflow.com/a/13343457/5409274 # https://stackoverflow.com/a/26733366/5409274 # https://stackoverflow.com/a/2853811/5409274 # https://stackoverflow.com/a/2853811/5409274 # https://www.linuxquestions.org/questions/other-%2Anix-55/how-can-i-run-a-command-on-another-shell-without-changing-the-current-shell-794580/ # https://www.tldp.org/LDP/abs/html/internalvariables.html # https://stackoverflow.com/a/4277753/5409274 # ========================================================================= # Enable following line to see the script commands # getting printing along with their execution. This will help for debugging. #set -o verbose E_BADARGS=85 if [ ! -n "$1" ] then echo "Usage: `basename $0` grep -nrs --color -w --include=\"*.{h,c}\" Testing ." echo "Usage: `basename $0` find . -name \"*.txt\"" exit $E_BADARGS fi # Create a temporary file TMPFILE=$(mktemp) # Add stuff to the temporary file #echo "echo Hello World...." >> $TMPFILE #initialize the variable that will contain the whole argument string argList="" #iterate on each argument for arg in "$@" do #if an argument contains a white space, enclose it in double quotes and append to the list #otherwise simply append the argument to the list if echo $arg | grep -q " "; then argList="$argList \"$arg\"" else argList="$argList $arg" fi done #remove a possible trailing space at the beginning of the list argList=$(echo $argList | sed 's/^ *//') # Echoing the command to be executed to tmp file echo "$argList" >> $TMPFILE # Note: This should be your last command # Important last command which deletes the tmp file last_command="rm -f $TMPFILE" echo "$last_command" >> $TMPFILE #echo "---------------------------------------------" #echo "TMPFILE is $TMPFILE as follows" #cat $TMPFILE #echo "---------------------------------------------" check_for_last_line=$(tail -n 1 $TMPFILE | grep -o "$last_command") #echo $check_for_last_line #if tail -n 1 $TMPFILE | grep -o "$last_command" if [ "$check_for_last_line" == "$last_command" ] then #echo "Okay..." bash $TMPFILE exit 0 else echo "Something is wrong" echo "Last command in your tmp file should be removing itself" echo "Aborting the process" exit 1 fi
quelle
Hier ist noch eine (funktionierende) Variante:
Dies öffnet ein neues Gnome-Terminal und führt dann im neuen Terminal Bash aus. Die RC-Datei des Benutzers wird zuerst gelesen, dann wird ein Befehl
ls -la
zur Ausführung an die neue Shell gesendet, bevor sie interaktiv wird. Das letzte Echo fügt eine zusätzliche neue Zeile hinzu, die zum Beenden der Ausführung erforderlich ist.gnome-terminal -- bash -c 'bash --rcfile <( cat ~/.bashrc; echo ls -la ; echo)'
Manchmal finde ich es auch nützlich, das Terminal zu dekorieren, z. B. mit Farbe zur besseren Orientierung.
gnome-terminal --profile green -- bash -c 'bash --rcfile <( cat ~/.bashrc; echo ls -la ; echo)'
quelle
Ausführen von Befehlen in einer Hintergrundshell
Fügen Sie einfach
&
am Ende des Befehls hinzu, z.quelle
$ bash --init-file <(echo 'some_command') $ bash --rcfile <(echo 'some_command')
Falls Sie die Prozessersetzung nicht verwenden können oder möchten:
Ein anderer Weg:
$ bash -c 'some_command; exec bash' $ sh -c 'some_command; exec sh'
sh
-nur so (dash
,busybox
):quelle
ENV=script
Teil) entfernt oder umformuliert würde, um nicht mit einem offensichtlichen Kopieren und Einfügen der oberen Antwort verwechselt zu werden.ENV
+sh
in den anderen Antworten vorhanden, aber meistens in Tonnen von Text vergraben oder von nicht benötigtem / nicht essentiellem Code umgeben. Ich glaube, eine kurze, klare Zusammenfassung wäre für alle von Vorteil.