1

Use-case:

I am writing a script that will accept --simulate which acts as a dry run and only prints the command rather than running it. When running normally (i.e. not with --simulate), the command that is run generates a LOT of output on the console, which I would ideally like to be able to hide.

Current

Currently, I am doing something along the lines of this (simplified a bit) and is running in a loop to process several compressed files that are in a proprietary archive format related to a windows game.

# flag variable
mode='';
if [[ "--simulate" == "$1" ]]; then
    mode="echo";
fi

# command is a long wine command that takes a mess of arguments
# and generates a LOT of output
${mode} command

Where I am Stuck

As I was thinking about changing ${mode} command to ${mode} command 2>&1 >/dev/null to avoid the console noise, I realized this would also have the effect of sending the echo output from --simulate to /dev/null as well.

I am aware that one option would be to just have an IF block / test and maintain multiple copies of the statement but curious if there is a better way.

Thought there might possibly be some way to do something like the following but couldn't find it on google / here so figured I'd ask just in case.

# flag variable
mode='';
redirectOutputTo='/dev/null';
if [[ "--simulate" == "$1" ]]; then
    mode="echo";
    redirectOutputTo="stdout";
fi

# If this is run as is, it will just create a file named 'stdout' in the script folder
# bc I assume that is not the real name. Ditto for using '&1'; just creates a file.
${mode} command 2>&1 >${redirectOutputTo}

Bash / OS Versions

if it makes a difference, here is what my system is running (Mint 19.3 x64):

$ bash --version|head -1
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)

$ uname -vo
#56~18.04.1-Ubuntu SMP Wed Jun 24 16:17:03 UTC 2020 GNU/Linux
1
  • 1
    You should be able to first set up another file descriptor with a choice of exec 9>&1 or exec 9>/dev/null, and then redirect your main command output with 1>&9. – Paul_Pedant Jul 17 '20 at 9:28
2

Use a shell function:

runmaybe () {
  if [[ $mode == "--simulate" ]]
  then echo $@
  else $@ 2>&1 > /dev/null
  fi
}

and this is a proof of concept:

#!/bin/bash

filethatwillsavestderr="/tmp/foo"
filethatwillsavestdout="/tmp/bar"

mode="--simulate" #switch this to another mode to see the effect

runmaybe () {
  if [[ $mode == "--simulate" ]]
  then echo "I should run '$@' but i'm not really doing it"
  else $@ > $filethatwillsavestdout 2> $filethatwillsavestderr
  fi
}

runmaybe ls
2
  • Thanks, apparently I really need some sleep... can't believe I missed that lol. Still kinda curious if stdin/stdout FD's can be referenced directly like I was trying above but this works. – zpangwin Jul 17 '20 at 4:22
  • You can use fifo's but you'll break the kiss-principle... – Garo Jul 17 '20 at 4:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.