Use a shell output value in shell script - shell

If I try following:
varReturn=$(ls)
echo $varReturn
it shows me the correct output of the listed elements in the directory.
But if I try this one:
varReturn=$(/opt/vc/bin/tvservice -n)
echo $varReturn
it doesn't show me the expected output :/
My goal is to check if an HDMI Port is connected or not.
It' very curious for me, why it works only for some commands.
I'm looking forward to getting some help here. I didn't figure out, what the problem is.
EDIT:
Now I've found another way and tried following:
varReturn=`tvservice -s`
echo $varReturn
this shows me the correct output:
But if I use another command, like this one:
varReturn=`tvservice -n`
echo $varReturn
It shows me no output at echo, but the output from the var (confusing).
It still shows me the output if I use following code:
varReturn=`tvservice -n`
#echo $varReturn
The output is shown without the blank space.

There is at least one problem with this code:
varReturn=$(/opt/vc/bin/tvservice -n)
echo $varReturn
# ^ missing double quotes around this variable
Adding those quotes will ensure that the variable is passed as a single argument to echo. Otherwise, echo sees a list of arguments and outputs each one, separated by a space.
The next possible issue is that the command is outputting to standard error, rather than standard output, so it won't be captured by $() or the old-fashioned equivalent ` `. To correct this, try:
output=$(/opt/vc/bin/tvservice -n 2>&1)
# ^ redirect standard error to standard output
echo "$output"

When you execute a shell command like varReturn=$(/opt/vc/bin/tvservice -n)
it will store the output to the variable only when the command executed successfully, else it will not hold any information because error/unsuccessful message will be redirected to standard error. Hence you have to redirected it to standard output like below:-
varReturn=$(/opt/vc/bin/tvservice -n 2>&1)
Now in both successful and unsuccessful execution case output will store in variable varReturn.

Related

Will variable be assigned to empty if the command for command substitution failed in shell scriping?

a=whatever
f(){return 1}
echo $a # this gives whatever
a=$(f)
echo $a # now a is empty
Is this because command returned non zero, so command substitution failed, thus a is set to empty? Is this a well defined behavior? Can't find it anywhere. Could you point me to the doc describing it?
I tried to grep something from a file and assign the result to the variable. So I did a=$(grep pattern file_not_exist). Then I see grep complained that the file does not exist. I wonder why this complaint message is not assigned to the variable rather than being printed out? Is it because of stdout and stderr?
No, it's not because the command failed that a is empty.
The command didn't produce any output data, so there is no data to be captured in a.
Revise the function to read:
f(){ echo Hello; return 1; }
Now run the command substitution. You'll find that a contains Hello. If you check $? immediately after the assignment, it contains 1, the status returned from the function. Exit statuses and command outputs are separate.
The documentation is in the GNU Bash manual for Command Substitution.

Why does this simple shell code give the output as "/dev/fd/11"?

I was trying out some redirection in my mac zsh shell.
I see that echo <(echo $c) outputs /dev/fd/11. I have no idea why this happens. Can someone explain?
Note: It doesn't matter if $c is initialised or not.
echo < '' returns zsh: no such file or directory: , so I am at a loss understanding what's going on.
Process expansion effectively "expands" to a file name. You are passing that file name as the argument to echo, which it dutifully writes back to standard output. If you had written
cat <(echo $c)
you would get as output, as I think you expected, the output of the command echo $c, because cat would open /dev/fd/11 for reading and output its contents.
Got the answer from here
https://unix.stackexchange.com/questions/17107/process-substitution-and-pipe
Looks like <(COMMAND) is slightly different that a the < (STDIN redirect) command
Pipes and input redirects shove content onto the STDIN stream. Process
substitution runs the commands, saves their output to a special
temporary file and then passes that file name in place of the command.
Whatever command you are using treats it as a file name. Note that the
file created is not a regular file but a named pipe that gets removed
automatically once it is no longer needed.

How does the echo command works in batch programming

I'm have started to learn batch programming to go a little more deeper in the Windows Machines. In Internet I have seen some commands with echo like "#echo off" or "on" and also this: "echo." but I don't know what are they doing. If anyone can explain me the functions of the echo command, please answer me.
The ECHO command in Windows CMD is used to print out text to the screen, display the actual setting of the Command-line which means when you do:
#echo off
The "C:\Users[User]" line before your command input will disappear.
You can restore it with:
#echo on
Here all functions of ECHO explained:
#echo [on/off] (to set the command-line settings)
echo [text] (to print text to the screen)
echo. (to print an empty line to the screen)
echo (displays the current setting of the command-line)
echo /? (displays help for the command ECHO)
I hope I was able to help you.
By default, every command executed in a batch file is also echoed to the output - not just the output of the command, but the command itself.
The echo command has three modes:
When called with some arguments AFTER a space, it will output the arguments.
When called as echo. (no space) it will output just a blank line.
When called with just the arguments on or off, it controls the behaviour of printing the commands as they execute.
So, the echo off command turns off the output at the start of the batch file. However, that command itself is still echoed before it has a chance to turn off the echoing. The # symbol has the effect of turning off the output for only the current command.
Combining the two, the #echo off at the start of a batch file turns off the echoing without itself being echoed.
It follows from this that if you try to echo just the word off, without quotes, it will turn off command printing instead. If you try to work around this by quoting the word "off", the output will include the quotes.
The answer, thanks to #JeffZeitlin's comment below, is:
In the presumably unusual case of wanting to echo just the word off or on (i.e., not a part of any other string), it turns out that echo.off and echo.on do the trick.
Partial answer is this: What does "#" mean in Windows batch scripts
The # before the command means do not print that command when running it.
The off argument tells the script not output any other commands, however without the # would output the echo off (since echoing hasn't yet been turned off)
The on argument turns command echoing back on.
Any other arguments are just echoed to the display

what is the meaning of FOOBAR=foobar followed by a shell command?

I see in shell scripts a variable assignment followed (without a semicolon) by a command. What is the meaning of that? It does not seem to affect this command, and it does not seem to affect the next command the way normal assignment would:
>echo $FOOBAR
>FOOBAR=1 echo $FOOBAR
>echo $FOOBAR
>
So, what does it do?
It sets that environment variable to that value only for that process.
Here, step by step, is what happens:
Original command: FOOBAR=1 echo $FOOBAR
Shell performs substitution: command is now FOOBAR=1 echo
Shell fork(2)s a new process
Environment variable is created in the new process: command is now echo (with $FOOBAR equal to 1)
New process is exec(3)ed: \n is output
New process exits and is reaped by the shell
At no point does the parent process see the assigned value of $FOOBAR.
On first run of echo $FOOBAR you will get empty result on your screen as the FOOBAR variable is not set yet.
Then when you set it to 1,and run it on the second time it will display 1.
Note: This value will be lost when you close your terminal where you wrote these. $ notation in shell and shell scripting in Unix like environments simply denotes a variable.
What happens in your case in second command i.e FOOBAR=1 echo $FOOBAR is that the line is not syntactically incorrect but it breaches the contract of equalto(=) which actually does not accept a space thus no error is thrown and FOOBAR=1 is just treated as a parameter and it fails while the command for echo executes successfully.
I would suggest try this :
FOOBAR=1
echo $FOOBAR
in different lines or
FOOBAR=1 ; echo $FOOBAR in one line.

How to redirect a command's output to a file whose name starts with & (ampersand)?

I'm trying to redirect a command's output to a file called e.g. &foo.txt, but nothing I've tried so far works.
The command echo test > "&foo.txt" gets interpreted as echo test >&foo.txt, and triggers the stream-to-stream redirection syntax (>&2). I've tried escaping with ^ to no avail as well.
It just hit me:
echo test > ".\&foo.txt"

Resources