sh arquivos de inicialização sobre o ssh

10

Eu tenho alguns comandos importantes que preciso executar antes de qualquer shell sh ser iniciado. Isso é necessário para passar comandos SSH no comando SSH ( ssh host somecommand ) e outros programas que executam comandos.

No meu .profile , tenho isto:

ihammerhands@wreckcreations:~> cat .profile
#specific environment and startup programs
export PS1="\u@wreckcreations:\w> "
export PYTHONPATH=~/python/lib/python2.4/site-packages
export PATH=$PATH:~/bin:~/python/bin

No entanto, isso falha:

W:\programming\wreckcreations-site\test-hg>ssh name@host echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

Observe as opções ausentes do PATH

Qual é o nome adequado para o perfil sh? Nota: Eu não tenho acesso root e não quero que isso seja aplicado a outros usuários. Existe outra maneira de fazer isso?

EDIT: aparece /bin/sh links para bash , o que não é surpreendente. O que é surpreendente é que o meu perfil ainda é ignorado. Alguma sugestão?

    
por TheLQ 17.12.2010 / 02:03

5 respostas

8

Parece importante notar que o comando que você mencionou na sua pergunta

ssh name@host echo $PATH

praticamente nunca será útil. A substituição de variável por $ PATH é feita pelo seu shell local e passada para ssh que executa eco no sistema remoto para imprimir o conteúdo da variável path, conforme ela é expandida em seu sistema local. Aqui está um exemplo de eu fazendo algo semelhante entre o meu Mac e uma máquina Linux na minha rede:

LibMBP:~ will$ echo $PATH
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren echo $PATH
will@warren's password: 
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren 'echo $PATH'
will@warren's password: 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
LibMBP:~ will$ 

Note como precisei usar aspas para impedir que meu shell local expandisse a variável.

    
por 17.12.2010 / 09:02
12

~/.profile é executado apenas por shells de login. O programa que chama o shell decide se o shell será um shell de login (colocando um - como o primeiro caractere do argumento zeroth na invocação do shell). Normalmente não é executado quando você efetua login para executar um comando específico.

O OpenSSH, em particular, chama um shell de login somente se você não especificar um comando. Então, se você especificar um comando, ~/.profile não será lido.

O OpenSSH permite definir variáveis de ambiente no lado do servidor. Isso deve ser ativado na configuração do servidor , com o PermitUserEnvironment directiva. As variáveis podem ser definidas no arquivo ~/.ssh/environment . Supondo que você use autenticação de chave pública, você também pode definir variáveis por chave em ~/.ssh/authorized_keys : adicione environment="FOO=bar" no início da linha relevante.

O ssh também suporta o envio de variáveis de ambiente. No OpenSSH, use a diretiva SendEnv em ~/.ssh/config . No entanto, a variável de ambiente específica deve ser ativada com uma diretiva AcceptEnv na configuração do servidor, portanto, isso pode não funcionar para você.

Uma coisa que acho que sempre funciona (por incrível que pareça) contanto que você esteja usando a autenticação de chave pública é para (ab) usar a opção command= no arquivo authorized_keys . Uma chave com uma opção command é boa apenas para executar o comando especificado; mas o comando no arquivo authorized_keys é executado com a variável de ambiente SSH_ORIGINAL_COMMAND definida para o comando especificado pelo usuário. Esta variável está vazia se o usuário não especificou um comando e, portanto, esperava um shell interativo. Então você pode usar algo assim em ~/.ssh/authorized_keys (claro, não será aplicável se você não usar essa chave para autenticar):

command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa …

Outra possibilidade é escrever scripts de wrapper no servidor. Algo como o seguinte em ~/bin/ssh-wrapper :

#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"

Em seguida, crie links simbólicos para esse script chamado rsync , unison , etc. Passe --rsync-path='bin/rsync' na linha de comando rsync e assim por diante para outros programas. Como alternativa, alguns comandos permitem que você especifique um fragmento de shell inteiro para ser executado remotamente, o que permite que você torne o comando autônomo: por exemplo, com o rsync, você pode usar --rsync-path='. ~/.profile; rsync' .

Existe outra avenida que depende do seu shell de login ser bash ou zsh. Bash sempre lê ~/.bashrc quando é invocado por rshd ou sshd, mesmo que não seja interativo (mas não se for chamado como sh ). Zsh sempre lê ~/.zshenv .

## ~/.bashrc
if [[ $- != *i* ]]; then
  # Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
  . ~/.profile
fi

## ~/.zshenv
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
  # Not a login shell, but this is an rsh/ssh session
  . ~/.profile
fi
    
por 17.12.2010 / 21:35
1

Normalmente, após o login, o bash lê os comandos de:

~ / .bash_profile
~ / .bashrc

Da página man do bash:

~/.bash_profile
The personal initialization file, executed for login shells

~/.bashrc
The individual per-interactive-shell startup file

    
por 17.12.2010 / 17:40
0

Eu fiquei sem tempo para testar isso, mas olhando as páginas man que encontrei:

man bash:        Quando o bash é iniciado de forma não interativa, para executar um script de shell, por exemplo,        procura a variável BASH_ENV no ambiente, expande seu valor se        aparece lá e usa o valor expandido como o nome de um arquivo para ler e        executar. O Bash se comporta como se o seguinte comando fosse executado:               if [-n "$ BASH_ENV"]; então . "$ BASH_ENV"; fi        mas o valor da variável PATH não é usado para procurar o nome do arquivo.

homem ssh:      ~ / .ssh / environment              Contém definições adicionais para variáveis de ambiente; Vejo              MEIO AMBIENTE, acima.

A combinação sugere como você pode fazer com que o ssh execute seu .profile

Infelizmente meu servidor tem o PermitUserEnvironment com o valor padrão de no, o que faz com que isso não funcione para mim (e como eu disse, não tenho tempo para brincar com ele mais).

    
por 17.12.2010 / 05:48
0

(removido ... só pode ter um hiperlink como novo usuário ~)

Atualizar

Desculpe, não vi que se trata de uma sessão não interativa, à qual o link acima não se aplica.

When Bash starts in SH compatiblity mode, it tries to mimic the startup behaviour of historical versions of sh as closely as possible, while conforming to the POSIX® standard as well. The profile files read are /etc/profile and ~/.profile, if it's a login shell.

If it's not a login shell, the environment variable ENV is evaluated and the resulting filename is taken as name of the startup file.

After the startup files are read, Bash enters the POSIX(r) compatiblity mode (for running, not for starting!).

Bash starts in sh compatiblity mode when:

  • the base filename in argv[0] is sh (:!: Attention dear uber-clever Linux users... /bin/sh may be linked to /bin/bash, but that doesn't mean it acts like /bin/bash :!:)

Então, a questão é: por que ele não é executado, mesmo que seu shell seja iniciado assim?

Fonte

    
por 17.12.2010 / 09:12