I want to check, if a user has access rights to a certain samba-share. I'm currently doing this using the command smbclient
in Version 4.3.11-Ubuntu
.
Apparently it is not a good idea to use the exit
status for evaluation of success, as described in this question: Exit codes of smbclient
But nevertheless I have some strange behaviour. I get different exit status when calling the program with Perls system
function.
perldoc -f system
tells me this:
The return value is the exit status of the program as returned by the "wait" call.
When calling from commandline I get EXIT 1
user@host:~$ 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
Calling the same whitin Perl I get EXIT 256
.
user@host:~$ 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
I also have the value 256
in the variable $?
whitin Perl.
Note: I get EXIT 0
in both (Bash and Perl) if I use the correct credentials.
My question: Why do I get different exit status from Bash and Perl if I use wrong credentials? How do I check correctly?
I use Perl v5.22 on Ubuntu 16.04.
The exit status returned by system
is a two-byte number, which packs the exit code returned by the program into high bits, while the low 8 bits are set if the process was killed by a signal. The low 7 bits are the signal number and the 8th bit shows whether the core was dumped.
So to get the actual exit of the program do as the next sentence from the docs you quote says
To get the actual exit value, shift right by eight
and 256 >> 8
gives us 1
.
The system
's return is available in the variable $?, interrogated as spelled out in 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;
}
The return is best saved or $?
examined right away, before it gets cleared.
The bit shifting can be avoided by using IPC::System::Simple, which returns the program's exit value directly. Thanks to daxim for the comment. To investigate the signal we still need $?
but this comes up far less frequently. The module simplifies system
and qx
use and error checking.