Batch use of | symbol - batch-file

What is "|" symbol used for in batch?
Because its not a command I cant use | /? to find out what it does, and if I have something like Stackoverflow|Stackoverflow (as an example) I'm told "stackoverflow is not a recognized as an internal or external command, operable program or batch file"

It's the pipe operator, or redirect operator. From TechNet:
Reads the output from one command and writes it to the input of another command. Also known as a pipe.
The pipe operator (|) takes the output (by default, STDOUT) of one command and directs it into the input (by default, STDIN) of another command. For example, the following command sorts a directory:
dir | sort
In this example, both commands start simultaneously, but then the sort command pauses until it receives the dir command's output. The sort command uses the dir command's output as its input, and then sends its output to handle 1 (that is, STDOUT).

The pipe operator | directs (pipes) the output of the first command to the standard input of the second command. So running
somecmd | anothercmd
Would first run somecmd, then gather the output of somecmd and run anothercmd, giving it the output of somecmd as input. You can read about it in innumerable places, just google "pipe command line" or something like it.

This character is used to chain commands.
There's a lot of documentation available on this. Wikipedia is probably a good place to start.

Related

How bash treats Here-docs

I'm working on a modest bash-like shell in C and I have a question on here-doc. For the moment my shell can execute here-doc only in first command.
ls | << eof wc
bash result :
> eof
0 0 0
my result :
> eof
10 10 63
(wc takes the result of ls, I have problem in my pipes but can't figure what.)
In this case, I can just do like ls doesn't exist I think.
wc | << eof wc
bash result
> eof
0 0 0
Here, bash executes the command with here-doc in first and execute the second (which it doesn't has input so it's freezing).
my result
> eof
I execute the here-doc first like bash, and eof works, but I have no result and then it's freezing due to the first wc.
So can I treat all cases like that? I execute the command with here doc first and cancel others except if they have to crash (like wc if it has no input)?
In a POSIX shell, redirections such as here-docs are associated with commands, and the pipe operator (|) separates commands. Thus here:
ls | << eof wc
eof
the here-doc is associated with the second command, wc (even though the redirection operator appears before the command name). It redirects that command's standard input to be from the content of the here-doc. The pipe operator also affects the second command's standard input, so an important question is which effect is applied last, as that is the one that will be effective. POSIX specifies for a pipeline of the form command1 | command2:
The standard output of command1 shall be connected to the standard
input of command2. The standard input, standard output, or both of a
command shall be considered to be assigned by the pipeline before any
redirection specified by redirection operators that are part of the
command.
(Emphasis added.) For what it's worth, the Bash docs say the same in their own words.
For your example, then, the here-doc should replace the output of ls as the input to wc, as it does when Bash processes the command.
In this case, I can just do like ls doesn't exist I think.
wc | << eof wc
bash result
> eof
0 0 0
Here, bash executes the command with here-doc in first and execute the second (which it doesn't has input so it's freezing).
Not exactly. The heredoc belongs to the second wc command, not the first, so it is the first that hangs waiting for interactive input. You can cause that to finish normally by typing a ctrl-D.
More importantly, if the idea is to ignore the ls, then why use two wc commands? Just drop the ls and the pipeline altogether, and use a single wc command:
<<eof wc
eof
# OR, equivalently and more conventionally,
wc <<eof
eof
So can I treat all cases like that? I execute the command with here
doc first and cancel others except if they have to crash (like wc if
it has no input)?
You seem to be trying to create specific rules where you should instead be observing more general ones. Each command has standard input, output, and error that are initially either inherited from the host shell or assigned as directed by pipe operators. Redirections, including from here-docs, are each part of an individual command, and their effects are applied on top of the initial standard stream assignments for that command. When multiple redirections apply to the same command, they are processed from left to right.
You cannot "cancel" commands based on the status of their standard streams. They will do whatever they do with the streams they receive. That might be nothing at all, terminating with an error, or exactly what they would have done anyway, among other possibilities. The shell doesn't know, so it cannot shortcut this.

How to redirect output to a file in C?

I am trying to, in C:
Read data from a file
Manipulate the data
Write manipulated data to another file
In the assignment requirements, it says to compile and run the program with the following commands:
gcc -o name name.c
./name inputFileName.ext > outputFileName.ext
I am unfamiliar with the " > " command. I have a couple of questions:
Online, it says that " > " redirects command output to a file, and I'm not sure exactly what "command output" means. I'm redirecting the output from my name.c file to the outputFileName.ext file. Does command output mean stdout? If so, which C keyword would I use to write information to the outputFileName.ext file from name.c as stdout?
When I open and read my input file, I need to access the file that was passed in from the command line. Does the " > " character count as another command line argument? Can I still access inputFileName.ext from main() with the statement " argv[1] " ?
Online, it says that > redirects command output to a file, and I'm not sure exactly what "command output" means.
"command output" refers to the stdout (Standard Output) stream of the program.
Do note that some shell commands are not separate programs but are actually shell builtins, though they'll still support output redirection. On Windows, most shell commands (like dir and del) are built-ins whereas on Linux/BSD/etc most shell commands are separate programs (like ls and mkdir)
If your program calls puts( "foobar" ); then running ./name from Bash will display "foobar" in your terminal emulator. But if you run ./name > file.txt then the "foobar" text will be written to file.txt and it will not be displayed in your terminal emulator.
Try it with the ls command, for example: ls -al > files.txt. This works on Windows too (dir /s > files.txt).
I'm redirecting the output from my name.c file to the outputFileName.ext file. Does command output mean stdout?
Yes.
If so, which C keyword would I use to write information to the outputFileName.ext file from name.c as stdout?
You don't. This is a shell/OS feature and is not part of C.
Let's clarify a few things:
>, < and a few other symbols (that are not relevant to your question) are control operators for your command line interpreter (a.k.a the shell). When the shell sees any of those, it assumes the command line arguments to your program are now finished. So in your case, your program will have argc=2 and argv = ["name ", "inputFileName.ext"].
The "redirection" thing means that whatever your program would normally write to the screen via the stdout (which is ulitized by default when calling printf() putchar(), puts()) will be written to the filename that comes after >. Your pogram is completely unaware of this fact. In your code, you should just assume you are printing on the screen. It is the responsibility of the one who executes the command to perform the redirection. (Also: "outputFileName.ext" does not need to exist, it will be created if it doesn't, but the redirection will override anything previously written in that file, so take extra care not to redirect to a .c file by accident or to your results of your previous execution, if you need them both)
< (not in your question, but closely related) works the opposite way around as you would imagine, with the program reading input from that file rather than from the keyboard. (obviously the file needs to exist now)
For the second part of your question, you can (and should) still access the name of the input file via the contents of argv[1]. You will open the file and read from it via some of the C functions that takes a file descriptor as an argument (like fscanf(), fgets(), getline()).
Finally, are you sure the command given to you is
./name inputFileName.ext > outputFileName.ext
and not
./name < inputFileName.ext > outputFileName.ext
?
The latter uses redirection both for input and for output, and you should not do anything different when reading, just read normally from stdin.

Another Linux command output (Piped) as input to my C program

I'm now working on a small C program in Linux. Let me explain you what I want to do with a sample Linux command below
ls | grep hello
The above command is executed in the below passion (Let me know if I've got this wrong)
ls command will be executed first
Output will be given to grep command which will again generate output by matching "hello"
Now I would like to write a C program which takes the piped output of one command as input. Means, In the similar passion of how "grep" program was able to get the input from ls command (in my example above).
Similar question has been asked by another user here, but for some reason this thread has been marked as "Not a valid question"
I initially thought we can get this as a command line argument to C program. But this is not the case.
If you pipe the output from one command into another, that output will be available on the receiving process's standard input (stdin).
You can access it using the usual scanf or fread functions. scanf and the like operate on stdin by default (in the same way that printf operates on stdout by default; in the absence of a pipe, stdin is attached to the terminal), and the C standard library provides a FILE *stdin for functions like fread that read from a FILE stream.
POSIX also provides a STDIN_FILENO macro in unistd.h, for functions that operate one file descriptors instead. This will essentially always be 0, but it's bad form to rely on that being the case.
If fact, ls and grep starts at the same time.
ls | grep hello means, use ls's standard output as grep's standard input. ls write results to standard output, grep waits and reads any output from standard input at once.
Still have doubts? Do an experiment. run
find / | grep usr
find / will list all files on the computer, it should take a lot of time.
If ls runs first, then OS gives the output to grep, we should wait a long time with blank screen until find finished and grep started. But, we can see the results at once, that's a proof for that.

is there a way to distinguish stderr in console output?

That is display both streams on console but distinguish somehow one from another.
Normally is that I don't know which lines are stderr they are mixed with normal output. If I redirect it to a file then I don't know when in relation to normal output the error happened. So is there a way so every line that comes from stderr would have some indicator like for example a string at the beginning like this:
c:\>command.exe
normal output
normal output
normal output
stderr: error message
normal output
stderr: error message
normal output
This is especially problem in compilers/make which spew lot of information and mix those two streams. I know I can prepend every line of text with given string using unix sed but I do not know how to use it with relation to main program. If I join two streams string will be prepended to every line. If I redirect stderr to file it won't be displayed on console + it will get out of context from stdout.
If the purpose is to distinguish error messages from normal output in the same screen, then it may be done via this trick:
anycompiler params ... 2>&1 1>&3 | findstr /N /A:4E "^"
This way the error messages appears preceded by a line number in yellow color on red background.
Previous answer extracted from: Batch - How can I redirect stderr and stdout from within the batch script itself?
If you redirect both outputs of previous line to a disk file, STDERR output will be preceded by a line number.

Check for UNIX command line arguments, pipes and redirects from a C program

I have some problem to figure out how I can maintain the pipe and redirect functionality of a shell once I find out that there are missing command line arguments.
If I for example use a scanf call, that will work with a re-direct or a pipe from a shell, but in absence of this I get a prompt, which I don't want.
I would like to accept command line arguments through argv[], a pipe or re-direct but I can't figure out how to do it with out getting the prompt. If I for example try something like this:
if(argc < 2)
exit(0);
Then the program will terminate if I try this:
echo arg | myProgram
Or this:
myProgram < fileWithArgument
I have tried to look this up but I always get some bash scripting reference.
The common way to handle situations like this is to check if the standard input stream is connected to a terminal or not, using isatty or similar functions depending on your OS. If it is, you take parameters from the command line, if not (it's been redirected), you read standard input.
Short version: You can't do it.
Pipeline and redirect specifiers are not arguments to your program, rather they are commands to the invoking shell and are processed before the running instance of your program even exists. The shell does no pass them to the program in argv or any other variable, and you can not discover them in any reliable way.
Neil has given you the way to determine if you are connected to a terminal.
In your examples you are using pipe redirection, both echo arg | myProgram and myProgram < filesWithArguments are sending output to the STDIN of your program.
If you want to read these values, use scanf or fread on the STDIN file descriptor.
If you are trying to get the file content as an argument list for your executable, you need to use it like this:
# This will pass `lala` as a variable
myProgram `echo lala`

Resources