Why exit status of command “ls” is difference between bash and csh shell?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












Why exit status is different between bash and csh shell?, In ls man:



Exit status:
0 if OK,

1 if minor problems (e.g., cannot access subdirectory),

2 if serious trouble (e.g., cannot access command-line
argument).


In order to test exit status of the command ls, let's say we have single file called ss saved in a folder. Let's list this file based on the status of it's characters using the wildcard ?



In csh Shell:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: No match.

ls -d ?z | echo $? #check exit status
0


In Bash:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: cannot access ?z: No such file or directory

ls -d ?z | echo $? #check exit status
2


It is the same command ls, but the exit status is different between csh shell and bash:



  • In csh shell the exit status is 0

  • In bash the exit status is 2

Now, the questions are:



1) Why the same command ls has difference exit status between bash and csh shell?



2) What is the importance of this difference in the command behaviour under bash and csh shell?










share|improve this question























  • I always thought bash IS a shell ("bourne again shell")?
    – RudiC
    1 hour ago














up vote
1
down vote

favorite












Why exit status is different between bash and csh shell?, In ls man:



Exit status:
0 if OK,

1 if minor problems (e.g., cannot access subdirectory),

2 if serious trouble (e.g., cannot access command-line
argument).


In order to test exit status of the command ls, let's say we have single file called ss saved in a folder. Let's list this file based on the status of it's characters using the wildcard ?



In csh Shell:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: No match.

ls -d ?z | echo $? #check exit status
0


In Bash:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: cannot access ?z: No such file or directory

ls -d ?z | echo $? #check exit status
2


It is the same command ls, but the exit status is different between csh shell and bash:



  • In csh shell the exit status is 0

  • In bash the exit status is 2

Now, the questions are:



1) Why the same command ls has difference exit status between bash and csh shell?



2) What is the importance of this difference in the command behaviour under bash and csh shell?










share|improve this question























  • I always thought bash IS a shell ("bourne again shell")?
    – RudiC
    1 hour ago












up vote
1
down vote

favorite









up vote
1
down vote

favorite











Why exit status is different between bash and csh shell?, In ls man:



Exit status:
0 if OK,

1 if minor problems (e.g., cannot access subdirectory),

2 if serious trouble (e.g., cannot access command-line
argument).


In order to test exit status of the command ls, let's say we have single file called ss saved in a folder. Let's list this file based on the status of it's characters using the wildcard ?



In csh Shell:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: No match.

ls -d ?z | echo $? #check exit status
0


In Bash:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: cannot access ?z: No such file or directory

ls -d ?z | echo $? #check exit status
2


It is the same command ls, but the exit status is different between csh shell and bash:



  • In csh shell the exit status is 0

  • In bash the exit status is 2

Now, the questions are:



1) Why the same command ls has difference exit status between bash and csh shell?



2) What is the importance of this difference in the command behaviour under bash and csh shell?










share|improve this question















Why exit status is different between bash and csh shell?, In ls man:



Exit status:
0 if OK,

1 if minor problems (e.g., cannot access subdirectory),

2 if serious trouble (e.g., cannot access command-line
argument).


In order to test exit status of the command ls, let's say we have single file called ss saved in a folder. Let's list this file based on the status of it's characters using the wildcard ?



In csh Shell:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: No match.

ls -d ?z | echo $? #check exit status
0


In Bash:



ls -d ss
ss

ls -d s?
ss

ls -d ?s
ss

ls -d ?z
ls: cannot access ?z: No such file or directory

ls -d ?z | echo $? #check exit status
2


It is the same command ls, but the exit status is different between csh shell and bash:



  • In csh shell the exit status is 0

  • In bash the exit status is 2

Now, the questions are:



1) Why the same command ls has difference exit status between bash and csh shell?



2) What is the importance of this difference in the command behaviour under bash and csh shell?







bash shell ls






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 13 mins ago

























asked 1 hour ago









Goro

6,62752865




6,62752865











  • I always thought bash IS a shell ("bourne again shell")?
    – RudiC
    1 hour ago
















  • I always thought bash IS a shell ("bourne again shell")?
    – RudiC
    1 hour ago















I always thought bash IS a shell ("bourne again shell")?
– RudiC
1 hour ago




I always thought bash IS a shell ("bourne again shell")?
– RudiC
1 hour ago










1 Answer
1






active

oldest

votes

















up vote
6
down vote



accepted










First, your ls -d ?z | echo $? in Bash is not measuring what you think it is. The pipeline all starts at once, and parameter expansion happens even before that, so echo $? is printing the return code of the previous command, not the one before the pipe. Under csh, it's not even doing that. That output is meaningless. If you run them as separate commands: ls -d ?z ; echo $? you will get informative output about what the actual exit code was.



sh -c 'exit 53' will work as a command for testing whether you're really getting the exit code from where you wanted.




Second, though you haven't told us, the error in your first example sounds like csh so I'll assume it's that. In that case, ls -d ?z is not running ls at all; the shell's wildcard expansion is failing and an error ("No match") has been reported, inhibiting the command from running. Bash, by default, passes non-matching globs through literally: it runs ls '?z', in effect, and you get an error from ls because that file doesn't exist. Regardless, the error code reported was from the previous line.



So the ls command, when it ran, had the same behaviour in all cases, it just wasn't running in the first place some of the time.




You can change Bash's (frankly, bad) behaviour with shopt -s failglob. It will then error out when a glob does not match:



/tmp$ ls ?z
ls: cannot access '?z': No such file or directory
/tmp$ shopt -s failglob
/tmp$ ls ?z
bash: no match: ?z


The first will have an exit code of 2, from ls, and for the second $? will be 1, from Bash itself.






share|improve this answer




















  • very nice explanation.. make sense. Many thanks ;-)
    – Goro
    1 hour ago







  • 1




    It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
    – Stéphane Chazelas
    37 mins ago






  • 1




    Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
    – Stéphane Chazelas
    35 mins ago










  • @Stéphane Chazelas. thank you for the highlights!
    – Goro
    20 mins ago










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f473565%2fwhy-exit-status-of-command-ls-is-difference-between-bash-and-csh-shell%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
6
down vote



accepted










First, your ls -d ?z | echo $? in Bash is not measuring what you think it is. The pipeline all starts at once, and parameter expansion happens even before that, so echo $? is printing the return code of the previous command, not the one before the pipe. Under csh, it's not even doing that. That output is meaningless. If you run them as separate commands: ls -d ?z ; echo $? you will get informative output about what the actual exit code was.



sh -c 'exit 53' will work as a command for testing whether you're really getting the exit code from where you wanted.




Second, though you haven't told us, the error in your first example sounds like csh so I'll assume it's that. In that case, ls -d ?z is not running ls at all; the shell's wildcard expansion is failing and an error ("No match") has been reported, inhibiting the command from running. Bash, by default, passes non-matching globs through literally: it runs ls '?z', in effect, and you get an error from ls because that file doesn't exist. Regardless, the error code reported was from the previous line.



So the ls command, when it ran, had the same behaviour in all cases, it just wasn't running in the first place some of the time.




You can change Bash's (frankly, bad) behaviour with shopt -s failglob. It will then error out when a glob does not match:



/tmp$ ls ?z
ls: cannot access '?z': No such file or directory
/tmp$ shopt -s failglob
/tmp$ ls ?z
bash: no match: ?z


The first will have an exit code of 2, from ls, and for the second $? will be 1, from Bash itself.






share|improve this answer




















  • very nice explanation.. make sense. Many thanks ;-)
    – Goro
    1 hour ago







  • 1




    It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
    – Stéphane Chazelas
    37 mins ago






  • 1




    Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
    – Stéphane Chazelas
    35 mins ago










  • @Stéphane Chazelas. thank you for the highlights!
    – Goro
    20 mins ago














up vote
6
down vote



accepted










First, your ls -d ?z | echo $? in Bash is not measuring what you think it is. The pipeline all starts at once, and parameter expansion happens even before that, so echo $? is printing the return code of the previous command, not the one before the pipe. Under csh, it's not even doing that. That output is meaningless. If you run them as separate commands: ls -d ?z ; echo $? you will get informative output about what the actual exit code was.



sh -c 'exit 53' will work as a command for testing whether you're really getting the exit code from where you wanted.




Second, though you haven't told us, the error in your first example sounds like csh so I'll assume it's that. In that case, ls -d ?z is not running ls at all; the shell's wildcard expansion is failing and an error ("No match") has been reported, inhibiting the command from running. Bash, by default, passes non-matching globs through literally: it runs ls '?z', in effect, and you get an error from ls because that file doesn't exist. Regardless, the error code reported was from the previous line.



So the ls command, when it ran, had the same behaviour in all cases, it just wasn't running in the first place some of the time.




You can change Bash's (frankly, bad) behaviour with shopt -s failglob. It will then error out when a glob does not match:



/tmp$ ls ?z
ls: cannot access '?z': No such file or directory
/tmp$ shopt -s failglob
/tmp$ ls ?z
bash: no match: ?z


The first will have an exit code of 2, from ls, and for the second $? will be 1, from Bash itself.






share|improve this answer




















  • very nice explanation.. make sense. Many thanks ;-)
    – Goro
    1 hour ago







  • 1




    It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
    – Stéphane Chazelas
    37 mins ago






  • 1




    Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
    – Stéphane Chazelas
    35 mins ago










  • @Stéphane Chazelas. thank you for the highlights!
    – Goro
    20 mins ago












up vote
6
down vote



accepted







up vote
6
down vote



accepted






First, your ls -d ?z | echo $? in Bash is not measuring what you think it is. The pipeline all starts at once, and parameter expansion happens even before that, so echo $? is printing the return code of the previous command, not the one before the pipe. Under csh, it's not even doing that. That output is meaningless. If you run them as separate commands: ls -d ?z ; echo $? you will get informative output about what the actual exit code was.



sh -c 'exit 53' will work as a command for testing whether you're really getting the exit code from where you wanted.




Second, though you haven't told us, the error in your first example sounds like csh so I'll assume it's that. In that case, ls -d ?z is not running ls at all; the shell's wildcard expansion is failing and an error ("No match") has been reported, inhibiting the command from running. Bash, by default, passes non-matching globs through literally: it runs ls '?z', in effect, and you get an error from ls because that file doesn't exist. Regardless, the error code reported was from the previous line.



So the ls command, when it ran, had the same behaviour in all cases, it just wasn't running in the first place some of the time.




You can change Bash's (frankly, bad) behaviour with shopt -s failglob. It will then error out when a glob does not match:



/tmp$ ls ?z
ls: cannot access '?z': No such file or directory
/tmp$ shopt -s failglob
/tmp$ ls ?z
bash: no match: ?z


The first will have an exit code of 2, from ls, and for the second $? will be 1, from Bash itself.






share|improve this answer












First, your ls -d ?z | echo $? in Bash is not measuring what you think it is. The pipeline all starts at once, and parameter expansion happens even before that, so echo $? is printing the return code of the previous command, not the one before the pipe. Under csh, it's not even doing that. That output is meaningless. If you run them as separate commands: ls -d ?z ; echo $? you will get informative output about what the actual exit code was.



sh -c 'exit 53' will work as a command for testing whether you're really getting the exit code from where you wanted.




Second, though you haven't told us, the error in your first example sounds like csh so I'll assume it's that. In that case, ls -d ?z is not running ls at all; the shell's wildcard expansion is failing and an error ("No match") has been reported, inhibiting the command from running. Bash, by default, passes non-matching globs through literally: it runs ls '?z', in effect, and you get an error from ls because that file doesn't exist. Regardless, the error code reported was from the previous line.



So the ls command, when it ran, had the same behaviour in all cases, it just wasn't running in the first place some of the time.




You can change Bash's (frankly, bad) behaviour with shopt -s failglob. It will then error out when a glob does not match:



/tmp$ ls ?z
ls: cannot access '?z': No such file or directory
/tmp$ shopt -s failglob
/tmp$ ls ?z
bash: no match: ?z


The first will have an exit code of 2, from ls, and for the second $? will be 1, from Bash itself.







share|improve this answer












share|improve this answer



share|improve this answer










answered 1 hour ago









Michael Homer

43.1k6108149




43.1k6108149











  • very nice explanation.. make sense. Many thanks ;-)
    – Goro
    1 hour ago







  • 1




    It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
    – Stéphane Chazelas
    37 mins ago






  • 1




    Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
    – Stéphane Chazelas
    35 mins ago










  • @Stéphane Chazelas. thank you for the highlights!
    – Goro
    20 mins ago
















  • very nice explanation.. make sense. Many thanks ;-)
    – Goro
    1 hour ago







  • 1




    It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
    – Stéphane Chazelas
    37 mins ago






  • 1




    Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
    – Stéphane Chazelas
    35 mins ago










  • @Stéphane Chazelas. thank you for the highlights!
    – Goro
    20 mins ago















very nice explanation.. make sense. Many thanks ;-)
– Goro
1 hour ago





very nice explanation.. make sense. Many thanks ;-)
– Goro
1 hour ago





1




1




It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
– Stéphane Chazelas
37 mins ago




It's probably tcsh. In csh (and tcsh) the exit status is in $status. But in tcsh, $? is also supported as an alternative.
– Stéphane Chazelas
37 mins ago




1




1




Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
– Stéphane Chazelas
35 mins ago




Note the difference thoug: with bash -O failglob (or zsh or fish) the command is cancelled if any of the globs fail to match while in csh, zsh -o cshnullglob and pre-Bourne Unix shells, the command is cancelled if none of the globs match any file.
– Stéphane Chazelas
35 mins ago












@Stéphane Chazelas. thank you for the highlights!
– Goro
20 mins ago




@Stéphane Chazelas. thank you for the highlights!
– Goro
20 mins ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f473565%2fwhy-exit-status-of-command-ls-is-difference-between-bash-and-csh-shell%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

Installing NextGIS Connect into QGIS 3?

One-line joke