Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you override function redirection in bash?

I recently discovered some bash code that used the little-known (well, little known to me anyway) feature of function redirection, such as the greatly simplified:

function xyzzy () {
    echo hello
} >/dev/null

When you call the function with a simple xyzzy, it automatically applies the redirections attached to the function regardless of what you've done when calling it.

What I'd like to know is if there's any way to override this behaviour in the call to the function itself, to see the message being generated. I'm reticent to change the file containing all the functions since (1) it's large, (2) it changes regularly, and (3) it's heavily protected by the group that supports it.

I've tried:

xyzzy >&1

to try to override it but the output still doesn't show up (possibly because >&1 may be considered a no-op).


In other words, given the script:

function xyzzy () {
    echo hello
} >/tmp/junk

rm -f /tmp/junk
echo ================
echo Standard output
echo ----------------
xyzzy # something else here
echo ================
echo Function capture
echo ----------------
cat /tmp/junk
echo ================

it currently outputs:

================
Standard output
----------------
================
Function capture
----------------
hello
================

What can I change the xyzzy call to, so as to get hello printed in the standard output section rather than the function capture section?

And this needs to be without trying to read the file /tmp/junk after it's created since the actual redirections may be to /dev/null so they won't be in a file.

like image 857
paxdiablo Avatar asked Jul 29 '13 07:07

paxdiablo


People also ask

How does redirection work in bash?

Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell. Redirection allows commands' file handles to be duplicated, opened, closed, made to refer to different files, and can change the files the command reads from and writes to.

What does >> mean in bash?

The > sign is used for redirecting the output of a program to something other than stdout (standard output, which is the terminal by default). The >> appends to a file or creates the file if it doesn't exist. The > overwrites the file if it exists or creates it if it doesn't exist.

How do I redirect a bash output?

The append >> operator adds the output to the existing content instead of overwriting it. This allows you to redirect the output from multiple commands to a single file. For example, I could redirect the output of date by using the > operator and then redirect hostname and uname -r to the specifications.


1 Answers

The only think I can think of would be to parse the output of declare -f function_name and remove the redirection.

This is perhaps the easiest approach. Note that you need to tailor the awk script to the specific function layout and it doesn't modify the body of the function at all. That means you can only turn off redirection at the top level. You could modify whole call trees of functions to turn off redirection but that would require a bash parser capable of recognising and changing function calls within the body.

The following script shows how to do it with your sample function. All the awk command does is create a new function my_xyzzy which mirrors the xyzzy function except for the final line, effectively turning it into:

function my_xyzzy () {
    echo hello
}

And the complete script as per specifications:

function xyzzy () {
    echo hello
} >/tmp/qqqq

declare -f xyzzy | awk '
    NR==1 {print "my_xyzzy ()"}
    NR==2 {prev=$0}
    NR>2  {print prev;prev=$0}
    END   {print "}"}' >$$.bash
. $$.bash
rm -f $$.bash

rm -f /tmp/qqqq
echo ================
echo Standard output
echo ----------------
my_xyzzy
echo ================
echo Function capture
echo ----------------
cat /tmp/qqqq
echo ================

The output of that is:

================
Standard output
----------------
hello
================
Function capture
----------------
cat: /tmp/qqqq: No such file or directory
================
like image 113
glenn jackman Avatar answered Nov 04 '22 00:11

glenn jackman