it-swarm-pt.com

arquivos de inicialização sh por ssh

Tenho alguns comandos importantes que preciso executar antes de iniciar qualquer sh Shell. Isso é necessário para passar comandos SSH no comando SSH (ssh Host somecommand) e outros programas que executam comandos.

No meu .profile Eu tenho isto:

[email protected]:~> cat .profile
#specific environment and startup programs
export PS1="\[email protected]:\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 [email protected] echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

Observe as opções de PATH ausentes

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. Há outra maneira de fazer isso?


EDITAR: Parece /bin/sh vincula a bash, o que não é surpreendente. O que é surpreendente é que meu perfil ainda é ignorado. Alguma sugestão?

10
TheLQ

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

ssh [email protected] echo $PATH

praticamente nunca será útil. A substituição da variável por $ PATH é feita por seu Shell local e passada para ssh, que executa echo no sistema remoto para imprimir o conteúdo da variável de caminho, conforme ela se expande em seu sistema local. Aqui está um exemplo de como faço algo semelhante entre meu Mac e uma máquina Linux em 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
[email protected]'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'
[email protected]'s password: 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
LibMBP:~ will$ 

Observe como precisei usar aspas para evitar que meu Shell local expandisse a variável.

8
wrosecrans

~/.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 zero na invocação do Shell). Normalmente não é executado quando você efetua login para executar um comando específico.

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

OpenSSH permite definir variáveis ​​de ambiente no lado do servidor. Isso deve ser habilitado em configuração do servidor , com a diretiva PermitUserEnvironment. 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 : adicionar environment="FOO=bar" no início da linha relevante.

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 habilitada com uma diretiva AcceptEnv na configuração do servidor, então isso pode não funcionar para você.

Uma coisa que acho que sempre funciona (por incrível que pareça), desde que você esteja usando a autenticação de chave pública, é (ab) usar o command= opção no authorized_keys arquivo . Uma chave com uma opção command é boa apenas para executar o comando especificado; mas o comando no authorized_keys arquivo é executado com a variável de ambiente SSH_ORIGINAL_COMMAND definido 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 se aplicará se você não usar esta 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##*/}" "[email protected]"

Em seguida, faça links simbólicos para este 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 snippet inteiro do Shell para ser executado remotamente, o que permite que você torne o comando autocontido: por exemplo, com rsync, você pode usar --rsync-path='. ~/.profile; rsync'.

Há outro caminho que depende do seu shell de login ser bash ou zsh. Bash sempre lê ~/.bashrc quando é invocado por rshd ou sshd, mesmo se não for 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
12

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

~/.bash_profile
~/.bashrc

Da página de manual do bash:

~/.bash_profile
O arquivo de inicialização pessoal, executado para shells de login

~/.bashrc
O arquivo de inicialização individual por Shell interativo

1
Alexander Pogrebnyak

Eu estou sem tempo para testar isso, mas olhando as páginas de manual que encontrei:

man bash: quando o bash é iniciado de forma não interativa, para executar um script Shell, por exemplo, ele procura a variável BASH_ENV no ambiente, expande seu valor se aparecer lá e usa o valor expandido como o nome de um arquivo para leia e execute. 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 pesquisar o nome do arquivo.

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

A combinação sugere como você pode fazer o ssh executar seu .profile

Infelizmente meu servidor tem PermitUserEnvironment para 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 mais com isso).

0
kasterma

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

Quando o Bash inicia no modo de compatibilidade SH, ele tenta imitar o comportamento de inicialização de versões históricas de sh o mais próximo possível, ao mesmo tempo em que está em conformidade com o padrão POSIX®. Os arquivos de perfil lidos são/etc/profile e ~/.profile, se for um Shell de login.

Se não for um Shell de login, a variável de ambiente ENV é avaliada e o nome do arquivo resultante é considerado o nome do arquivo de inicialização.

Depois que os arquivos de inicialização são lidos, o Bash entra no modo de compatibilidade POSIX (r) (para execução, não para iniciar!).

O Bash começa no modo de compatibilidade sh quando:

  • o nome do arquivo base em argv [0] é sh (:!: Atenção, queridos usuários uber-espertos do Linux .../bin/sh pode estar vinculado a/bin/bash, mas isso não significa que age como/bin/bash :! :)

Portanto, a questão é: por que ele não o executa, embora seu Shell seja iniciado assim.

Fonte

0
phant0m