Frage Verwenden Sie .bashrc ohne sftp zu brechen


Mein Problem ist, dass ich ein paar Variablen setzen muss und jedes Mal ein paar Zeilen ausgeben muss, wenn ich mich in der SSH-Shell anmelde, und gleichzeitig muss ich in der Lage sein, sftp zu verwenden, um Dateien über Filezilla zu tarnen.

Nun, wie in der openssh FAQ unter http://www.openssh.org/faq.htmlWenn Ihre Startskripte jede Art von Ausgabe wiedergeben, wird sftp durcheinander gebracht. Entweder verzögert es sich auf unbestimmte Zeit oder es kommt zu Fehlern mit einer "Verbindung geschlossen vom Server mit Exit-Code 128".

Ich habe versucht, Lösungen wie .bashrc in .bash_profile zu verschieben oder den folgenden Code in .bashrc zu verwenden:

if [ "$TERM" != "dumb" ]
then
   source .bashc_real
fi

Und:

if [ "$TERM" = "xterm" ]
then
   source .bashc_real
fi

Nichts funktioniert jedoch. Mein Shell-Terminal ist bash, und ich verbinde mit sftp mit filezilla.


18
2018-03-07 06:24


Ursprung




Antworten:


Versuchen Sie es stattdessen

if [ "$SSH_TTY" ]
then
   source .bashc_real
fi

22
2018-03-07 06:28





Mikes Antwort wird wahrscheinlich funktionieren. Aber es lohnt sich, darauf hinzuweisen, dass Sie dies sorgfältig durchführen können, indem Sie auswählen, welche Startup-Dateien den ausführlichen Inhalt enthalten sollen. Auf der bash man-Seite:

Wenn bash als interaktive Login-Shell oder als nicht interaktive Shell mit der Option --login aufgerufen wird, liest und führt sie zuerst Befehle aus der Datei / etc / profile aus, falls diese Datei existiert. Nach dem Lesen dieser Datei sucht sie nach ~ / .bash_profile, ~ / .bash_login und ~ / .profile in dieser Reihenfolge und liest und führt Befehle aus der ersten aus, die existiert und lesbar ist. Die Option --noprofile kann verwendet werden, wenn die Shell gestartet wird, um dieses Verhalten zu verhindern.

Wenn eine interaktive Shell gestartet wird, die keine Login-Shell ist, liest bash   und führt Befehle von ~ / .bashrc aus, wenn diese Datei existiert. Das mag sein   gesperrt mit der Option --norc. Die Option --rcfile file wird erzwungen   Bash zum Lesen und Ausführen von Befehlen aus der Datei anstelle von ~ / .bashrc.

Die sftp / scp-Tools starten eine interaktive Nicht-Login-Shell, daher wird .bashrc als Quelle verwendet. Viele Distributionen liefern .bashrc aus .bash_profile oder umgekehrt, so dass es verwirrend werden kann. Ein guter Trick, um die Sauberkeit Ihrer Login-Umgebung zu testen, besteht darin, sich mit einem Befehl zu verbinden, der auf die gleiche Weise scp / sftp connect simuliert. Zum Beispiel: ssh myhost /bin/true zeigt dir genau, was scp / sftp sieht, wenn sie sich verbinden.

Eine einfache Demo:

insyte@mazer:~$ echo "echo Hello from .profile" > .profile
insyte@mazer:~$ echo "echo Hello from .bashrc" > .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
Hello from .bashrc
sazerac:~ insyte$

insyte@mazer:~$ rm .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
sazerac:~ insyte$

Der erste Test führt dazu, dass scp / sftp / rsync usw. bricht. Die zweite Version wird gut funktionieren.


15
2018-03-07 06:48



Sehr nützliche Information, danke. - Droidzone
Dem stimme ich nicht zu "Die sftp / scp-Tools starten ein interaktiv Nicht-Login-Shell " wie können wir nicht wirklich interagieren mit der Schale. Aber ich verstehe nicht warum .bashrc wäre Quelle für scp oder ssh host command. - pynexj
Der Begriff "interaktiv" ist nicht subjektiv. Es ist ein Begriff, der von bash verwendet wird, um einen seiner Startmodi zu beschreiben. Es ist eine Tatsache, dass sftp / scp eine "interaktive Nicht-Login-Shell" startet. Fühlen Sie sich frei, mit den Entwicklern darüber zu streiten, ob die Beschaffung von .bashrc in diesem Fall nicht angemessen ist. Ich sage dir nur, was es macht. - Insyte
Bashaufgerufen von scp oder ssh host command ist in der Tat nicht interaktiv. Ich habe das gerade im bash Handbuch gefunden: "Bash versucht zu bestimmen wenn es mit seinem Standardeingang ausgeführt wird, der mit einer Netzwerkverbindung verbunden ist, wie es normalerweise vom Remote-Shell-Daemon ausgeführt wird rshd oder der Secure Shell-Daemon sshd. Wenn bash feststellt, dass es auf diese Weise ausgeführt wird, liest es Befehle aus und führt sie aus ~/.bashrc, wenn diese Datei existiert und lesbar ist. " Hier ist der interessante Geschichte. - pynexj
Siehe auch den Abschnitt Remote-Nicht-Login nicht interaktive Shells im diese Wiki-Seite. - pynexj


Wenn Sie csh verwenden:

if ($?prompt)
  ... interactive stuff ...

Und wenn es Bash ist:

if [[ $- == *i* ]]; then
  ... interactive stuff ...
fi

oder alternativ bash reguläre Ausdrücke verwenden:

if [[ $- =~ i ]]; then
  ... interactive stuff ...
fi

Diese Zeilen sollten Zeilen vorausgehen, in denen Sie etwas zurückgeben / zurückgeben.


3
2018-03-07 11:11



Hallo, könnten Sie bitte den Code erklären. Ich weiß das $? ist die Rückkehrstufe des vorherigen Befehls. Ich verstehe nicht $? Prompt und $ -, obwohl. Oder ist csh spezifisch? - Droidzone
@Droidzone: $?var im csh gibt 1 if zurück var ist definiert und sonst 0. $- im bash hätte das i char in seinem Wert, wenn die Shell interaktiv ist. - pynexj
Sollte update antworten, um $ zu erklären - ist eine spezielle Variable von Shell-Optionen. sehen stackoverflow.com/questions/5163144/... - maninvan


Mikes Lösung funktionierte auch für mich. Aber da meine Standard-Shell TCSH ist, musste ich das Update wie folgt (in .tcshrc) leicht bearbeiten:

if ( $?SSH_TTY ) then
    exec /bin/bash
endif

Ich dachte nur, ich würde es für alle teilen.


1
2018-01-12 05:07