Jak ustawić $ PATH tak, aby polecenie `ssh user @ host` działało?

131

Nie mogę ustawić nowej zmiennej $ PATH tak, aby była używana podczas wykonywania poleceń za pośrednictwem ssh user@host command. Próbowałem dodać export PATH=$PATH:$HOME/new_pathdo ~ / .bashrc i ~ / .profile na zdalnej maszynie, ale wykonanie ssh user@host "echo \$PATH"pokazuje, że zmiana nie została odebrana (pokazuje / usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin: / usr / games). Na zdalnym komputerze działa Ubuntu 8.04.

Jestem pewien, że mógłbym włamać się do / etc / profile, ale nie jest to czyste rozwiązanie i działa tylko wtedy, gdy ma się uprawnienia administratora.

Denver Gingerich
źródło
1
Próbowałem dodać export PATH=$PATH:$HOME/new_pathzarówno ~ / .bash_login, jak i ~ / .bash_profile (oprócz wcześniej wypróbowanych ~ / .bashrc i ~ / .profile). Ani jedno, ani drugie nie działa. W obu przypadkach musiałem stworzyć plik.
Denver Gingerich
W moim szczególnym przypadku nie jest łatwo zmodyfikować polecenie wysłane do ssh. Używam stfufs ( guru-group.fi/too/sw/stfufs ), który sam konstruuje polecenie ssh. Zdaję sobie sprawę, że jego metoda nie jest świetnym rozwiązaniem, ale byłoby miło naprawić to bez modyfikowania elementów.
Denver Gingerich
Możesz umieścić ssh wrapper na sposób stfufsa, wywołać prawdziwy ssh ze zmodyfikowanymi argumentami, jeśli to łatwiejsze
Hasturkun

Odpowiedzi:

185

Jak powiedział grawity, ~ / .bashrc jest tym, czego potrzebujesz, ponieważ jest pozyskiwane z nieinteraktywnych powłok niezalogowanych.

Spodziewam się, że problem, który masz, dotyczy domyślnego pliku Ubuntu ~ / .bashrc. Zwykle zaczyna się od czegoś takiego:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Chcesz umieścić cokolwiek dla powłok nieinteraktywnych przed tą linią.

singpolyma
źródło
2
Tak, przesunąłem export PATH=$PATH:$HOME/new_pathpowyżej tej linii i zadziałało. Dzięki!
Denver Gingerich
3
.bashrc jest zawodne. man bash: "Bash próbuje określić, kiedy jest uruchomiony, gdy jego standardowe wejście jest podłączone do połączenia sieciowego". Działa to na RHEL, ale nie na Archlinux. Musiałem edytować / etc / environment, aby zmienić domyślną PATH
basin
Należy dodać wzmiankę o .zshenvdla zsh użytkowników, zajęło mi trochę czasu, aby znaleźć go w komentarzach na innych odpowiedzi
Mike
na MacOS Catalina musiałem umieścić plik „zshenv” w / etc / zshenv (z moimi ścieżkami eksportu).
Doomd
30

Czy masz ~/.bash_loginlub ~/.bash_profile?

Bash w trybie interaktywnym sprawdza te pliki i używa pierwszego istniejącego w następującej kolejności:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

Więc jeśli masz ~/.bash_profile, to wszelkie zmiany, które ~/.profilewprowadzisz, pozostaną niewidoczne.

Bash w trybie nieinteraktywnym czasami odczytuje plik ~/.bashrc(który jest również często pobierany ze skryptów interaktywnych). Przez „czasami” mam na myśli, że jest zależny od dystrybucji: dość dziwne, jest opcja włączania tego w czasie kompilacji . Debian umożliwia ~/.bashrcodczyt, podczas gdy np. Arch nie.

ssh wydaje się używać trybu nieinteraktywnego, więc ~/.bashrcpowinno wystarczyć. Kiedy mam takie problemy, zwykle dodaję kilka ech, aby zobaczyć, jakie pliki są uruchamiane.

user1686
źródło
Dodanie ech pomogło ... ale wciąż szukam sposobu, aby wykonać 'ssh -X remotemachine "xterm"' i mieć pełną ścieżkę systemową / użytkownika z / etc / profile i ~ / home / username / .bash_profile. Jeśli pobiorę oba pliki w poleceniu, to działa ... ale jest brzydkie:).
Jess
Skąd wiesz, że „Bash w trybie nieinteraktywnym odczytuje plik ~/.bashrc”? Nie widzę tego stwierdzenia na stronie podręcznika. Dzięki
nknight
4
Jeśli chcesz, aby źródłem ~/.bashrcbyła nieinteraktywna powłoka niezalogowana , wydaje się, że musisz dodatkowo ustawić zmienną środowiskową BASH_ENV; patrz superuser.com/a/585699/100843 . W przypadku nieinteraktywnych powłok logowania prawdopodobnie musiałbyś zmodyfikować jeden z trzech wymienionych skryptów startowych.
nknight
3
Dla ZSH plik nieinteraktywny to:.zshenv
matematyka
2
@math .zshenvzawsze pochodzi; nie ma znaczenia, czy jest interaktywny, czy nie.
JoL
19

Dokumentacja ssh mówi:

Jeśli podano polecenie, jest ono wykonywane na zdalnym hoście zamiast w powłoce logowania.

dlatego nie działa dodawanie do plików bashrc. masz jednak następujące możliwości:

  1. Jeśli PermitUserEnvironmentopcja jest ustawiona w konfiguracji sshd, możesz dodać ustawienie PATH do~/.ssh/environment

  2. ssh remotemachine 'bash -l -c "somecommand"'

Hasturkun
źródło
1. Nie jest ustawiony w mojej konfiguracji sshd i man sshd_configmówi, że jest domyślnie wyłączony, więc jest mało prawdopodobne, że to rozwiązanie zadziała dla większości ludzi. 2. To by zadziałało, ale nie mogę łatwo zmodyfikować polecenia wysłanego do ssh (patrz drugi komentarz do mojego pytania).
Denver Gingerich
1
1. Nie działa zgodnie z oczekiwaniami, ponieważ w środowisku ~ / .ssh / nie możesz dodawać ścieżek do PATH, ponieważ $ PATH nie zostanie rozwiązane.
not2savvy
8

Zawsze możesz powiedzieć:

ssh remotemachine 'export PATH=wedontneedastinkingpath; echo $PATH'
Chas. Owens
źródło
To rozwiązanie nie wymaga żadnych zmian na zdalnym komputerze, co jest dobrą rzeczą.
Ronny Andersson,
2

Oprócz odpowiedzi @signpolyma, będziesz musiał dodać swój eksport przed tymi liniami

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac
Miłego kodowania
źródło
Właściwie to właśnie całkowicie wykomentowałem te linie - znalezione w ~ / .bashrc na pulpicie Ubuntu 16.04 LTS. Nie, wszystko działa. Ustaw także PermitUserEnvironment na yes.
Ernie S,
2

Po prostu miałem ten sam problem, rozwiązałem go za pomocą:

ssh user@remotehost PATH=\$HOME/bin:\$PATH\; remote-command
Indie
źródło