Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash : How to store STDOUT (&1) pointer in a variable

Here is a simple (and maybe dummy) question in an as-simple-as-the-question scenario.

I want to store my output file in a variable :

#!/bin/bash
LOG=/var/log/myown/backup.log

So I can build my script this way:

#!/bin/bash
LOG=/var/log/myown/backup.log
echo "Backup créé le $(date)" >>$LOG

Also, I'd like to make this possible for the LOG variable to point to STDOUT.

Then I could simply change the value of LOG as in LOG=&1 so it does not writeout to a file but to STDOUT.

like image 486
MensSana Avatar asked Jul 21 '14 17:07

MensSana


People also ask

How to save stdout output to a file in Linux?

1>/tmp/tar_stdout : save the stdout output to a temp file. 2>/tmp/tar_stderr : save stderr output to a file. Return code of the command (exit status) is saved into the $ {?} variable. Thanks for contributing an answer to Unix & Linux Stack Exchange! Please be sure to answer the question. Provide details and share your research! But avoid …

How to redirect stdout to a file in Bash?

Most bash commands output data STDOUT to the console, which causes it to appear in the console. The data can be redirected to a file by attaching it to its contents using the command >>. So, we have a certain data file, to which we can add other data using this command:

What are stdin stderr and stdout in Bash?

Whenever running any command in the terminal, stdin, stderr, and stdout are three data streams that bash creates. If you’re familiar with the command line, you may already have taken advantage of these features. Essentially, they allow piping/redirecting data from one command to another.

How to pipe stderr and stdout to the next command?

If you want to pipe both the stderr and stdout to the next command, then use the “|&” instead. Now we know how these streams work, let’s have a look at how you can redirect them. Piping is a form of redirection.


2 Answers

Is this what you need?

LOG=/dev/stdout

Or perhaps:

LOG=/var/log/myown/backup.log
exec 4> "$LOG"  ## exec >>4 "$LOG" to append
echo "Backup créé le $(date)" >&4

Or finally:

LOG=/var/log/myown/backup.log
exec 4> "$LOG"  ## exec >>4 "$LOG" to append
LOG_FD=4  ## Change to 1 to put back to stdout.
echo "Backup créé le $(date)" >&"$LOG_FD"

You can also use a function for convenience:

function log {
    echo "$1" >&"$LOG_FD"
}
log "Backup créé le $(date)"
like image 133
konsolebox Avatar answered Oct 20 '22 16:10

konsolebox


In modern (4.1+) versions of bash, you can use expansions to refer to file descriptors:

log_fd=1                # hardcode FD 1 as output source
echo "Hello" >&$log_fd  # ...and use that value

This is extra handy with automatic file descriptor allocation, also added in 4.1:

exec {log_fd}>log.txt   # open log.txt on an automatically-assigned free FD
                        # ...and save that FD number in log_fd
echo "Hello" >&$log_fd  # write to log.txt on that FD

You can't put the & itself into the variable -- which is actually better design; otherwise, you couldn't redirect to a filename starting with a literal &, and any program wherein a user could specify a filename would allow the user to target stdout/stderr/etc -- but that's no loss of flexibility, since you can open any filename on any FD using exec in its redirection-enacting usage mode.

like image 35
Charles Duffy Avatar answered Oct 20 '22 15:10

Charles Duffy