How to get output redirect as parameter in bash? - bash

I would like to know if it's possible to get the output redirection file name as a parameter in bash?
For example :
./myscript.sh parameter1 > outputfile
Is there a way to get "outputfile" as a parameter like $2? In my script I have to do few operations in outputfile but I don't know which file I have to update... The second problem is, this script is already running and used by several tasks so I cannot change the user input...
Best regards

Redirections are not parameters to the program. When a program's output is redirected, the shell opens the file and connects file descriptor 2 to it before running the program. The program then simply writes to fd 2 (aka stdout) and it goes to the file.
On Linux and similar systems you can use /dev/stdout, which is a symbolic link to the process's stdout file.

Related

Can the pipe operator be used with the stdout redirection operator?

We know that:
The pipe operator | is used to take the standard output of left side command as the standard input for the right side process.
The stdout redirection operator > is used to redirect the stdout to a file
And the question is, why cannot ls -la | > file redirect the output of ls -la to file? (I tried, and the file is empty)
Is it because that the stdout redirection operator > is not a process?
Is it because that the stdout redirection operator > is not a process?
In short, yes.
In a bit more detail, stdout, stderr and stdin are special file descriptors (FDs), but these remarks work for every FD: each FD refers to exactly one resource. It can be a file, a directory, a pipe, a device (such as terminal, a hard drive etc) and more. One FD, one resource. It is not possible for stdout to output to both a pipe and a file at the same time. What tee does is takes stdin (typically from a pipe, but not necessarily), opens a new FD associated with the filename provided as its argument, and writes whatever it gets from stdin to both stdout and the new FD. This copying of content from one to two FDs is not available from bash directly.
EDIT: I tried answering the question as originally posted. As it stands now, DevSolar's comment is actually more on point: why does > file, without a command, make an empty file in bash?
The answer is in Shell Command Language specification, under 2.9.1 Simple commands. In the first step, the redirection is detected. In the second step, no fields remain, so there is no command to be executed. In step 3, redirections are performed in a subshell; however, since there is no command, standard input is simply discarded, and the empty standard output of no-command is used to (try to) create a new file.

What does the redirection operator "<" do in shell scripts?

I came across the below shell command:
$prog.sh < file_name.json
I know it reads from a file, but how and where does prog.sh load the file?
Every program has three open file handles at startup, one of which is standard input. Normally, the file handles are inherited from the parent process. The < operator tells the shell that, instead of passing its standard input to prog.sh, to open file_name.json instead and give that file handle to prog.sh as its standard input.
$prog.sh < file_name.json
As you rightly guess. The < is meant for redirecting the input from a file so that your script will read from the file which will be the (temporary) stdin(fd0).
it read from a file, but how and where prog.sh will load the file
It depends on how you plan to go about it. Any command in the script that expects an input from the stdin will now read from the file. The new line character in the text file (usually) stands for the ↵ in the stdin.

Assigning stdin to file also assigns stdout to that file

I executed the following bash script:
#!/bin/env bash
exec 0<log
My understanding is that it permanently reassigns the stdin for this bash process to the log file. So, when I ran
ls > log
I expected that I was passing "ls" to stdin. Since I have not reassigned stdout, I was also expecting to see the result of the "ls" command in the terminal (where I normally see stdout). However, I saw the output of "ls" in the log file. Why is stdout in the log file and not the terminal?
ls writes to whatever file it is given for standard output. Without a redirection, that is whatever file it inherits from its parent (your script). With the redirection, you are explicitly providing the file log for standard output.
This is independent of whatever else the file log might be used for.

Auxiliary piping for shell input output redirection

In my script I need to output special commands to a pre-defined file descriptor along with usual stdout-stderr and listen to the commands in another program without creating a file.
Essentially it's like redirection with a pipe, but with a roundabout through using some other file descriptor(s) or socket or device:
Usual way with redirecting stdout(1) to stdin(0):
> program1 | program2
What I need (some redirection, which uses other descriptor e.g. 5):
> exec "open descr 5 <>5"
> program1 ??5?? & program2 <5 &
program1 "knows" about the descriptor number 5 and just outputs to it with fwrite(5, ...), program2 uses a usual stdin redrection.
How can I do this roundabout redirection in shell?
You can't. The only way to do anything like a semaphore is to use a fifo file, but you've said you don't want to make a file. The file descriptors you define, will only exist in that shell, so any subprocess or another program would be unaware of them.

How can i print output of a command to a file in Batch Script?

I am trying to call a command in batch file using "call" method and whatever is the output of that command, I want to write in a file.
I went through from this link but cannot find the answer.
I am using this command
call %confPath% GetIniString %datFile% Keyname name >%newFile% >&1
but it creates a empty file always. How can i write the output of above command in the file?
Thanks in advance.
>%newFile% redirects the standard output to a file. in >&1, the 1 stands for standard output, and if no stream is specified, standard output is the default, so >&1 redirects on itself, although it was already redirected with the first command. So, this is illegal and shouldn't produce a file at all. In my tests, this just aborts with an errormessage.
The usual idiom 2>&1, OTOH, redirects stream 2, which is standard ERROR, to standard output, which ensures that both output and error messages end up in the file.

Resources