Small confusion about redirection in Linux

  • Thread starter Thread starter shivajikobardan
  • Start date Start date
  • Tags Tags
    Linux Shell
AI Thread Summary
In Linux, the bash shell processes redirection before counting command arguments, meaning the redirection operator (>) is effectively removed from the command line during this phase. When a command like "zcho It is cold today! > winter.txt" is executed, the shell clears the contents of "winter.txt" before it attempts to execute the command. If the command fails, as in this case where "zcho" is not found, the file remains empty because it was cleared prior to execution. This behavior highlights the importance of understanding how redirection works in bash, especially compared to other operating systems like Windows. Overall, the redirection operator's evaluation occurs before any command execution, leading to potential data loss if not carefully managed.
shivajikobardan
Messages
637
Reaction score
54
TL;DR Summary
Small confusion about redirection in Linux
https://linux-training.be/funhtml/ch18.html

Note that the bash shell effectively removes the redirection from the command line before argument 0 is executed. This means that in the case of this command:
Code:
echo hello > greetings.txt

the shell only counts two arguments (echo = argument 0, hello = argument 1). The redirection is removed before the argument counting takes place.
I feel it's telling before counting the number of arguments, redirection operator is ignored.

But later it says how it affects output erasing file case.

While scanning the line, the shell will see the > sign and will clear the file! Since this happens before resolving argument 0, this means that even when the command fails, the file will have been cleared!

Code:
[paul@RHELv4u3 ~]$ cat winter.txt 
It is cold today!
[paul@RHELv4u3 ~]$ zcho It is cold today! > winter.txt
-bash: zcho: command not found
[paul@RHELv4u3 ~]$ cat winter.txt 
[paul@RHELv4u3 ~]$

So can you explain how
Code:
zcho It is cold today! > winter.txt command processes internally?

My estimate

1) > is ignored

2) Number of arguments are count. There are 2 arguments "It is cold today!" and winter.txt

3) then what? i don't know.
 
Technology news on Phys.org
1) > is seen and the file is cleared

2) The shell counts the number of arguments. There are 5 arguments "zcho", "It", "is", "cold" and "today!"

3) Command fails, so nothing is written in file winter.txt (that was previously cleared)
 
  • Like
Likes shivajikobardan
shivajikobardan said:
I feel it's telling before counting the number of arguments, redirection operator is ignored.
It didn't say "ignored", it said "removed". All that part is saying is that the redirection operator and everything after it are not counted as arguments. That part says nothing about what the shell does with the redirection operator. For that you have to look elsewhere--as in, the other part you quoted, which tells you that the redirection operator is evaluated before resolving argument 0.
 
You need to be careful, as Windows has a different take on command-line arguments.

As an example, bash will expand filename args with * or ? in the name to the full list of matching filenames, whereas windows leave it as is when passing to a command leaving the command to do the expansion itself by calling the GLOB module.

I know you didn't ask about Windows but as a programmer, you should be keenly aware of the similarities and differences in the common platforms when it comes to arguments and redirections. Even shells like bash and csh can have differences that you need to watch out for.
 
thank you all.
 
shivajikobardan said:
Code:
echo hello > greetings.txt
Code:
[paul@RHELv4u3 ~]$ cat winter.txt
It is cold today!
[paul@RHELv4u3 ~]$ zcho It is cold today! > winter.txt
-bash: zcho: command not found
[paul@RHELv4u3 ~]$ cat winter.txt
[paul@RHELv4u3 ~]$

So can you explain how
Code:
zcho It is cold today! > winter.txt command processes internally?

My estimate

1) > is ignored

2) Number of arguments are count. There are 2 arguments "It is cold today!" and winter.txt

3) then what? i don't know.
Let's look at "zcho today >text.txt":

Bash likely follows this logic:
1) Since the first word "zcho" is not a recognized as part of the bash syntax, it presumes it to be an executable file. So it needs to set up a call to create a new process - probably some form of "spawn".
2) It will continue to scan the command line until it reaches the ">". At that point, it has the full argument list and has probably already put it in the form needed for the spawn operation. So the executable file name, the arguments, and argument counts are all ready.
3) It then parses the ">text.txt", creates file "text.txt", and opens it. Since text.txt already existed, its content is overwritten. So bash now has an open handle to the empty file text.txt that will be used as the "stdout" for the new process.
4) Bash then uses the argument list and the stdout handle to attempt the spawn - but it gets back an error code. So it issues the error message and closes the text.txt.
 
Since zcho is not a builtin command then the shell will search the directories listed in the path environment parameter in the order they are listed. If not found it will print an error message to stderr and stop processing the command.

if zcho is found in one of the path directories then it will launch a process to execute the command and wait for a status return from the command unless you’ve used the trailing & for background execution. The shell needs to process the command string to determine stdin, stdout, stderr redirections along with the existing environment to be passed as arguments to the process it’s launching.

look at the way a program can launch a process via a function call to see what the shell must do prior to launching the process.
 
.Scott said:
Bash likely follows this logic
Not exactly.

.Scott said:
1) Since the first word "zcho" is not a recognized as part of the bash syntax, it presumes it to be an executable file. So it needs to set up a call to create a new process - probably some form of "spawn".
This does happen in the case of an unrecognized command, but it's not necessary to create the issue the OP describes. Even a shell built-in will trigger it if the built-in command fails for some other reason. Consider this shell session:

Bash:
peter@localhost:~$ echo "Test" > test.txt
peter@localhost:~$ cat test.txt
Test
peter@localhost:~$ source nonexistent-file > test.txt
bash: nonexistent-file: No such file or directory
peter@localhost:~$ cat test.txt
peter@localhost:~$

So what the shell does to spawn an external process is irrelevant to the issue the OP is asking about.
 
  • #10
PeterDonis said:
So what the shell does to spawn an external process is irrelevant to the issue the OP is asking about.
He asked about what it did internally ("command processes internally?"). From what I can tell, he wanted to know why the text file was emptied.
The key thing is that text file is overwritten before any attempt is made to execute the command.
 
  • #11
.Scott said:
The key thing is that text file is overwritten before any attempt is made to execute the command.
Yes, agreed.
 
Back
Top