2017-07-20 7 views
1

Je souhaite vérifier si un utilisateur a des droits d'accès sur un certain partage Samba. Je suis en train de le faire en utilisant la commande smbclient dans Version 4.3.11-Ubuntu.Statut de sortie différent dans le système Perls que dans Bash

Apparemment, ce n'est pas une bonne idée d'utiliser le statut exit pour l'évaluation du succès, tel que décrit dans cette question: Exit codes of smbclient

Mais néanmoins, j'avoir un comportement étrange. Je reçois un état de sortie différent lorsque j'appelle le programme avec la fonction Perls system.

perldoc -f system me dit ceci:

La valeur de retour est l'état de sortie du programme tel qu'il est retourné par l'appel « attendre ».

Lorsque vous appelez de commandline je reçois EXIT 1

[email protected]:~$ smbclient //server/share MyFalsePassword --user=any.user -c "cd somefolder;"; echo "EXIT $?" 
WARNING: The "syslog" option is deprecated 
session setup failed: NT_STATUS_LOGON_FAILURE 
EXIT 1 

L'appel de la même whitin Perl je reçois EXIT 256.

[email protected]:~$ perl -E 'say "EXIT " . system("smbclient //server/share MyFalsePassword --user=any.user -c \"cd somefolder;\"");' 
WARNING: The "syslog" option is deprecated 
session setup failed: NT_STATUS_LOGON_FAILURE 
EXIT 256 

J'ai aussi la valeur 256 dans la variable $? whitin Perl.

Remarque: Je reçois EXIT 0 à la fois (Bash et Perl) si j'utilise les informations d'identification correctes.

Ma question: Pourquoi est-ce que j'obtiens un statut de sortie différent de Bash et Perl si j'utilise de fausses informations d'identification? Comment puis-je vérifier correctement? Je utilise Perl v5.22 sur Ubuntu 16.04.

+1

Un peu plus d'arrière-plan: http://blogs.perl.org/users/mauke/2011/09/exit-statuses-and-how-works.html – melpomene

Répondre

3

L'état de sortie retourné par system est deux -byte nombre, qui emballe le code de sortie retourné par le programme en bits élevés, tandis que les 8 bits bas sont définies si le processus a été tué par un signal.Les 7 bits les plus bas sont le numéro du signal et le 8ème indique si le noyau a été vidé.

Donc, pour obtenir la sortie réelle du programme faire comme la phrase suivante à partir des documents que vous citez dit

Pour obtenir la valeur réelle de sortie, décalage vers la droite par huit

et 256 >> 8 donne nous 1.

Le retour de system est disponible dans variable $?, interrogé comme précisé dans system

if ($? == -1) { 
    print "failed to execute: $!\n"; 
} 
elsif ($? & 127) { 
    printf "child died with signal %d, %s coredump\n", 
     ($? & 127), ($? & 128) ? 'with' : 'without'; 
} 
else { 
    printf "child exited with value %d\n", $? >> 8; 
} 

Le retour est le meilleur enregistré ou $? examiné tout de suite, avant qu'il ne soit effacé.


peut être évité Le décalage de bit par using IPC::System::Simple, qui renvoie la valeur de sortie du programme directement. Merci à daxim pour le commentaire. Pour étudier le signal nous avons encore besoin de $? mais cela revient beaucoup moins fréquemment. Le module simplifie l'utilisation et la vérification des erreurs.

+0

Ce n'est pas assez compliqué. Doit être mentionné ici: https://stackoverflow.com/questions/799968/whats-the-difference-between-perls-backticks-system-and-exec J'ai lu la phrase que vous avez citée auparavant. Votre explication aide beaucoup à comprendre les docs. Je vous remercie! N'y a-t-il pas de module sur CPAN, offrant une interface qui ne nécessite pas d'opérations sur les bits? C'est une douleur pour quiconque a besoin de regarder ce code plus tard. –

+0

* "Si le retour du système est différent de zéro, vous pouvez interroger la variable $?" * Il n'est pas nécessaire de vérifier '$? 'Ainsi que la valeur de retour de' system': ils sont identiques. – Borodin

+0

@Borodin Je voulais relier l'examen '$?' À ce qui est le plus souvent fait, 'system (...) == 0 ou ...' (ou 'system (...) et ...'). Je veux dire que les gens vérifient normalement le retour de 'system' en premier. Il est sorti un peu maladroit peut-être :( – zdim

2

Ce n'est pas très bien documenté, et les informations les plus utiles est perldoc perlvar qui dit ce

  • $ CHILD_ERROR
  • $?

    L'état renvoyé par la dernière fermeture du tuyau, commande backtick, appel réussi à wait() ou waitpid() ou à l'opérateur system(). Ceci est juste le mot d'état de 16 bits renvoyé par l'appel système Unix wait() traditionnel (ou bien est constitué pour lui ressembler). Ainsi, la valeur de sortie du sous-processus est vraiment ($? >> 8) et $? & 127 indique le signal, le cas échéant, où le processus est mort, et $? & 128 indique s'il y a eu un vidage du cœur.

Ainsi, une valeur de retour de 256 de system correspond à une valeur de sortie de 256 >> 8, qui est le 1 que vous attendiez