Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9158139
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T13:10:49+00:00 2026-06-17T13:10:49+00:00

I have a shell function called run, that normally just treats its parameters as

  • 0

I have a shell function called “run”, that normally just treats its parameters as a command line (i.e., as though ‘run()’ had not been used.) However, if the script is run in a $TESTMODE, ‘run()’ will echo its parameters, instead:

run ()
{
  cmd="$@"
  if [ -z "$TESTMODE" ]; then
    $cmd
  else
    echo "### RUN: '$cmd'"
  fi
}

The idea is, the command run rm -Rf / would normally attempt to delete your entire root filesystem. But, if $TESTMODE is defined, then it instead echos

### RUN: rm -Rf /

It works pretty well, until you attempt to use run() on a command-line that includes redirection:

run which which
run which bash >quiet

In which case, when $TESTMODE is defined, the desired echo will never be seen by human eyes:

$ rm quiet
$ TESTMODE=yes ./runtest.sh
### RUN: 'which which'
$ cat quiet
### RUN: 'which bash'

I attempted to correct for this with string replacement:

run ()
{
  cmd="$@"
  if [ -z "$TESTMODE" ]; then
    $cmd
  else
    cmd=${cmd//\>/\\>}
    cmd=${cmd//\</\\<}
    echo "### RUN: '$cmd'"
  fi
}

… which seemed promising in a command-line test:

$ test1="foo >bar"
$ echo $test1
foo >bar
$ test2=${test1//\>/\\>}
$ echo $test2
foo \>bar

… but failed miserably (no apparent change in behavior) from within my bash script.

Help? I’m sure this has something to do with quoting, but I’m not sure exactly how to address it.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T13:10:50+00:00Added an answer on June 17, 2026 at 1:10 pm

    It’s not a matter of escaping; the redirection happens before your function even starts, and is outside of the function’s control. For example, when bash sees the command run which bash >quiet, bash first redirects output to the file “quiet”, then executes the “run” function with the arguments “which” and “bash”. Anything your function sends to stdout will naturally go into the file “quiet”.

    There’s also another problem with your script. When you store the command in a variable (cmd="$@"), it looses the breaks between arguments. For example, you can’t tell if the command was run touch "foo bar" or run touch "foo" "bar" — in either case, $cmd is set to “touch foo bar”. This might be ok for printing the command, but since you’re executing it in that form it’s likely to cause trouble. To solve this, either avoid storing it in a variable, or store it as an array (cmd=("$@"); then execute it as "${cmd[@]}").

    There are a couple of ways around the output redirection problem. You could send output to stderr instead of stdout:

    run ()
    {
      if [ -z "$TESTMODE" ]; then
        "$@"
      else
        echo "### RUN: '$*'" >&2
      fi
    }
    

    …but this has a few issues: it still executes the redirect rather than printing it (run which bash >quiet will create an empty file named “quiet”, then print “### RUN: ‘which bash'”).

    Also, if stderr has been redirected, it will print to that instead of the terminal. This might be either good or bad, depending on your intent. Another possibility would be to send directly to the terminal with echo "### RUN: '$*'" >/dev/tty. Possible problem here: it’ll fail if there’s no tty (e.g. in a cron job).

    Final note: in the echo command, I used $* instead of $@ because I wanted the entire command treated as a single string with spaces instead of a series of strings. This makes the printout ambiguous (e.g. run touch "foo bar" vs. run touch "foo" "bar" — both would print ### RUN: 'touch foo bar'), but that isn’t nearly as important as executing the command correctly. If you want unambiguous logging, you have to do something more complex like this:

    echo "### RUN:" >&2
    printf " %q" "$@" >&2
    echo >&2
    

    printf’s %q format will use an unambiguous (and shell-executable) format for the command and its arguments.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a shell function that is called from inside my map function. The
I have a python function that makes a subprocess call to a shell script
I have an auto-generated file each day that gets called by a shell script.
I have a clojure program that at some point executes a function called db-rebuild-files-table
This question is based on the thread . I have the shell function function
I have the following to execute shell commands using Node: function puts( error, stdout,
I have a Bourne Shell script that has several functions in it, and allows
Have a shell script that reads the files in a particular directory. #!/bin/bash for
I have a function that looks like this: def getCurrentShow(hour=(localtime().tm_hour),day=datetime.datetime.now().strftime('%A')): return Schedule.objects.get(hour=hour,day=day).show so I
I have a function $result = create_watermark( 'input_file_name' ,'output_file_name'); I have directory called /images

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.