web-dev-qa-db-fra.com

SCP ne fonctionne pas quand écho dans .bashrc?

J'ai deux utilisateurs dans Fedora:

  1. Wani
  2. racine (assez évident!)

Mon contenu de .bashrc de l'utilisateur Wani est:

# .bashrc
echo "Hello"
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# User specific aliases and functions

Maintenant, une fois connecté à root, je tape les commandes suivantes:

[root@Dell Wani]# touch try.txt
[root@Dell Wani]# service sshd start
[root@Dell Wani]# scp try.txt Wani@localhost:~/
Wani@localhost's password: 
Hello
[root@Dell Wani]# 

Maintenant, je me connecte à Wani et tape:

[Wani@Dell ~]$ cat try.txt
cat: try.txt: No such file or directory
[Wani@Dell ~]$ 

Maintenant, je me connecte à nouveau à root et saisis la même commande avec -v:

[root@Dell Wani]# scp -v morph.log Wani@localhost:
Executing: program /usr/bin/ssh Host localhost, user Wani, command scp -v -t -- .
OpenSSH_5.6p1, OpenSSL 1.0.0j-fips 10 May 2012
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to localhost [127.0.0.1] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.6
debug1: match: OpenSSH_5.6 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.6
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'localhost' is known and matches the RSA Host key.
debug1: Found key in /root/.ssh/known_hosts:2
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-     with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_0' not found

debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_0' not found

debug1: Unspecified GSS failure.  Minor code may provide more information


debug1: Unspecified GSS failure.  Minor code may provide more information


debug1: Next authentication method: publickey
debug1: Trying private key: /root/.ssh/id_rsa
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Next authentication method: password
Wani@localhost's password: 
debug1: Authentication succeeded (password).
Authenticated to localhost ([127.0.0.1]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env XMODIFIERS = @im=none
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: scp -v -t -- .
Hello
[root@Dell Wani]# debug1: client_input_channel_req: channel 0 rtype exit-status      reply      0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 1664, received 1976 bytes, in 0.1 seconds
Bytes per second: sent 22961.5, received 27266.8
debug1: Exit status 0

(Et après j'appuie sur Entrée)

[root@Dell Wani]# 

Quelqu'un peut-il, s'il vous plaît, nous éclairer sur ce qui s'est exactement passé ici? Pourquoi le fichier n'a-t-il pas été copié dans Wani à partir de la racine?

68
Nehal J Wani

L'utilisation de echo dans un .bashrc cassera scp, car scp s'attend à voir ses données de protocole sur les canaux stdin/stdout. Voir https://bugzilla.redhat.com/show_bug.cgi?id=20527 pour plus d'informations sur ce sujet.

Il existe quelques solutions de contournement disponibles:

  • Condition sur le drapeau 'interactif' (par exemple, case $- in *i* comme suggéré par tripleee)
  • Utilisez l'utilitaire tty pour détecter un shell interactif (par exemple if tty > /dev/null ou if [ -t 0 ])
  • Vérifiez la valeur de $SSH_TTY

Je suppose que vous devriez utiliser celui qui vous convient le mieux. Malheureusement, je ne sais pas quelle est la meilleure option (la plus portable/la plus fiable).

64
nneonneo

Pour ajouter aux options de nneonneo, vous pouvez également conditionner avec le drapeau interactif avec

if [[ $- =~ "i" ]]

que je pense est peut-être le moyen le plus clair à Bash.

18
Drew Ogle

Ça marche pour moi
Dans .bashrc, ajoutez la première ligne en tant que:

if [ -z "$PS1" ]; then
    return
fi

https://superuser.com/questions/690735/can-i-tell-if-im-in-an-scp-session-in-mon-bashrc

13
Manoj Ashok

Le default Ubuntu .bashrc contient le fragment de code suivant qui traite déjà le problème:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
    *) return;;
esac
7
Blauhirn

Dans .bashrc, utilisez plutôt STDERR en sortie:

echo "# Important Notice" >&2

Mise à jour: ne l'utilisez pas! Nous avons récemment eu un problème en raison de l’échec d’un outil (source fermée) en raison de echo de STDERR dans .bashrc. L'outil (à l'aide de rcp) ne prévoyait aucune sortie, ni sous STDOUT ni STDERR. Et ça a collé quand ça a eu l'écho. Leçon apprise: créez des comptes séparés pour les humains et pour les machines (scripts), ou arrêtez simplement de manipuler via .bashrc

4
bal

Le moyen le plus portable de tester un shell interactif semble être:

test -t 0
if [ $? -eq 0 ]
then
    # interactive
    ;
else
    # non-interactive
    ;
fi
1
Jambock

la solution de nneonneo a également fonctionné pour moi. Mais comme mon shell par défaut est TCSH, je devais modifier légèrement le correctif comme suit (en .tcshrc):

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

Je pensais que je partagerais pour le bénéfice de tous.

0
Vijay Padiyar
if [ 0 -eq $(shopt -q login_Shell; echo $?) ]; then
  echo "do something?"
fi

La source

0
vesperto

Si vous utilisez une version de RHEL (Red Hat Enterprise Linux) ou une variante, déposez un script exécutant la variable echo, ou ce que vous voulez, dans /etc/profile.d/.

0
Everett Toews