- Execute command without terminal output [duplicate]
- 3 Answers 3
- How to silence output in a Bash script?
- 9 Answers 9
- Redirect stderr to stdout
- Redirect stdout to File
- Redirect stderr and stdout to File
- Redirect stderr and stdout to /dev/null
- Useful variations:
- If output of bash command is empty, do something
- 2 Answers 2
- Hiding output of a command
- 3 Answers 3
Execute command without terminal output [duplicate]
Let me give a bit of background to my question. I am using a terminal RSS reader newsboat which allows for the usage of macros to operate on links. For example, I have a macro running cd ~/videos && youtube-dl %u , which will download a youtube video to ~/videos . However, the output of youtube-dl will be printed in my terminal until the download is complete and for this time I cannot continue using newsboat . I am wondering how I could phrase the command so that it is executed “somewhere else” so that I can immediately continue using the terminal from which it is run.
Why the downvote? I know that applications like youtube-dl are off-topic, but I think my question is not.
Please specify: Are you asking about discarding output, or are you asking about job control (e. g. running processes in the background)?
3 Answers 3
If you don’t need the output at all then redirect it to /dev/null
otherwise you can redirect into a file:
yourcommand > /somwhere/file 2>&1
And as you run the command from another application and you want use your news reader immediately you may want to run the command in the background. I am not sure how it works in this newsboat, but in a shell you can send programs into the backround with &
yourcommand > /somwhere/file 2>&1 &
2>&1 redirects the stderr (2) to the stdout (1). As the stdout is redirected to a file, it writes the stderr to the same file.
To run command silently in background, which will «survive» even if terminal will be closed afterwards, use screen in detached mode:
to reattach screen with the command running execute
To detach reattached screen press CTRL+A+D .
Without screen you should execute your command with nohup , thus the process will run if the terminal is closed afterwards, like the screen utility:
nohup your_command(-s) &>/dev/null &
Your question starts asking one thing, but then goes into asking about another thing.
The first thing you ask about is discarding output. This is easily done with redirection:
The second thing you ask about is running a command «somewhere else» so that you can continue using the terminal. This is called «Job Control».
You can execute any command in the background using the shell’s & command separator. Compare the behavior of the following two commands:
If a job is already running and you need to use the terminal for other things, and you want the job to complete, you can use Ctrl — Z to suspend the job and bg to tell it to continue in the background:
$ (sleep 10; echo hello) ^Z [1]+ Stopped ( sleep 10; echo hello ) $ bg [1]+ ( sleep 10; echo hello ) & $ echo farewell farewell $ fg ( sleep 10; echo hello ) hello
This link has some fairly good reading about job control with bash .
How to silence output in a Bash script?
I have a program that outputs to stdout and would like to silence that output in a Bash script while piping to a file. For example, running the program will output:
% myprogram % WELCOME TO MY PROGRAM % Done.
#!/bin/bash myprogram > sample.s
From what I recall, redirecting output to a file causes it to not be echoed to the terminal. What’s not working for you?
9 Answers 9
If it outputs to stderr as well you’ll want to silence that. You can do that by redirecting file descriptor 2:
# Send stdout to out.log, stderr to err.log myprogram > out.log 2> err.log # Send both stdout and stderr to out.log myprogram &> out.log # New bash syntax myprogram > out.log 2>&1 # Older sh syntax # Log output, hide errors. myprogram > out.log 2> /dev/null
The «&>» line is a shorter version of what I just posted. I haven’t come across that shortcut before. Upvoting.
git.savannah.gnu.org/cgit/bash.git/tree/CHANGES#n2208 indicates that >>& was introduced in 4.0. There is no mention of &> but the CHANGES only go back to 2.0 so I think that means it was already in 1.x.
git blame on redir.c points to a 1998 commit for the oldest occurrence still in the current code base.
Redirect stderr to stdout
This will redirect the stderr (which is descriptor 2) to the file descriptor 1 which is the the stdout.
Redirect stdout to File
Now when perform this you are redirecting the stdout to the file sample.s
Redirect stderr and stdout to File
Combining the two commands will result in redirecting both stderr and stdout to sample.s
Redirect stderr and stdout to /dev/null
Redirect to /dev/null if you want to completely silent your application.
The last one is missing a redirection operator; it should be myprogram >/dev/null 2>&1 (notice the wedge before /dev/null and the order of the redirections).
scriptname >/dev/null 2>/dev/null
For newer bash (no portable):
This doesn’t work. It actually creates a file named — and &> is a non-portable bourne shell extension.
The portable equivalent echo moo 1>&- produces an error because file descriptor 1 is closed: -bash: echo: write error: Bad file descriptor
If you are still struggling to find an answer, specially if you produced a file for the output, and you prefer a clear alternative: echo «hi» | grep «use this hack to hide the oputut 🙂 «
If you want STDOUT and STDERR both [everything], then the simplest way is:
#!/bin/bash myprogram >& sample.s
then run it like ./script , and you will get no output to your terminal. 🙂
the «>&» means STDERR and STDOUT. the & also works the same way with a pipe: ./script |& sed that will send everything to sed
man bash (under «Redirecting Standard Output and Standard Error») says &> and >& are equivalent but the first (&>) is preferred. However |& is the only way to do this for pipes.
Useful variations:
- Get only the STDERR in a file, while hiding any STDOUT even if the program to hide isn’t existing at all. (does not ever hang):
stty -echo && ./programMightNotExist 2> errors.log && stty echo
Note: This answer is related to the question «How to turn off echo while executing a shell script Linux» which was in turn marked as duplicated to this one.
To actually turn off the echo the command is:
(this is, for instance; when you want to enter a password and you don’t want it to be readable. Remember to turn echo on at the end of your script, otherwise the person that runs your script won’t see what he/she types in from then on. To turn echo on run:
If output of bash command is empty, do something
Hi I am new to bash so please excuse me if I have a really silly/easy question. I am writing a script which allows the user to change their region (for wireless). What I am wanting to do is put a check in place, so if they type in an incorrect value, it brings up the prompt again to input the region. I want to do this by checking if the output of the command sudo iw reg set $reg , if it is a correct input, there is no output. But if it is a wrong input, it gives an error message. I tried to do this but im getting an error:
#!/bin/bash echo "Please set a region: " read reg if [(sudo iw reg set $reg) -ne 0]; then echo "Please set a valid region: " read reg else echo "Setting reg as $reg" sudo iw reg set $reg fi
2 Answers 2
You can use the -z test, type help test in Bash to learn more ( test is the same as the [ command).
You should only call iw reg set once, unless it fails.
echo "Please set a region: " while true # infinite loop do # read in the region: read reg # try the command, and catch its output: output=$( sudo iw reg set "$reg" 2>&1 ) if [ -z "$output" ] then # output is empty - success - leave the loop: break else # output is non-empty - continue: echo "Please set a valid region. " fi done
This snippet checks the success condition you gave in your question (empty output), but it should be noted that usually exit codes should be used if possible.
Note the 2>&1 operator redirecting stderr to stdout so any output on either file descriptor will be considered a failure.
Hiding output of a command
I have a script where it checks whether a package is installed or not and whether the port 8080 is being used by a particular process or not. I am not experienced at all with bash, so I did something like this:
if dpkg -s net-tools; then if netstat -tlpn | grep 8080 | grep java; then echo "Shut down server before executing this script" exit fi else echo "If the server is running please shut it down before continuing with the execution of this script" fi # the rest of the script.
However when the script is executed I get both the dpkg -s net-tools and the netstat -tlpn | grep 8080 | grep java outputs in the terminal, and I don’t want that, how can I hide the output and just stick with the result of the if s? Also, is there a more elegant way to do what I’m doing? And is there a more elegant way to know what process is using the port 8080 (not just if it’s being used), if any?
3 Answers 3
To hide the output of any command usually the stdout and stderr are redirected to /dev/null .
Explanation:
1. command > /dev/null : redirects the output of command (stdout) to /dev/null
2. 2>&1 : redirects stderr to stdout , so errors (if any) also goes to /dev/null
&>/dev/null : redirects both stdout and stderr to /dev/null . one can use it as an alternate of /dev/null 2>&1
Silent grep : grep -q «string» match the string silently or quietly without anything to standard output. It also can be used to hide the output.
In your case, you can use it like,
if dpkg -s net-tools > /dev/null 2>&1; then if netstat -tlpn | grep 8080 | grep java > /dev/null 2>&1; then #rest thing else echo "your message" fi
Here the if conditions will be checked as it was before but there will not be any output.
Reply to the comment:
netstat -tlpn | grep 8080 | grep java > /dev/null 2>&1 : It is redirecting the output raised from grep java after the second pipe. But the message you are getting from netstat -tlpn . The solution is use second if as,
if [[ `netstat -tlpn | grep 8080 | grep java` ]] &>/dev/null; then