1

I'd like to have a general script that runs a command and appends it to a file.

My attempt was the following (stored in an executable called ./action).

#!/bin/bash
#runs command and logs result to "./actions"

if "$@"; then
    echo "#"$(date)"(success)" >> ./actions
else
    read -p "Exit code is fail. Still record to ./actions (y)? " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]
    then
        exit 1
    fi
    echo "#"$(date)"(failed)" >> ./actions
fi
echo "$@" >> ./actions

The problem I have is that e.g.:

./action touch "new file"

runs correctly but bash saves only

touch new file

Obviously touch new file is different from touch "new file".

How to fix this script to log commands with quoted arguments correctly?

1 Answer 1

1

Interesting question. I think that what you want to do is not fully possible but you can get really close using %q format specifier available in Bash printf implementation:

%q causes printf to output the corresponding argument in a format that can be reused as shell input.

Final lines in your script could look like this:

printf "%q\n" "$@" | tr '\n' ' ' >> actions
printf "\n" >> actions

This will not record commands exactly as you type them but in the form that is suitable for use in shell and if you typed these recorded commands you'd get the result that was originally intended. For example, after doing this:

./action touch "new file"

you get:

#Wed Sep 4 14:10:57 CEST 2019(success)
touch new\ file

Or after doing this:

./action echo 'one
two
three
'

you get:

#Wed Sep 4 14:11:44 CEST 2019(success)
echo $'one\ntwo\nthree\n'

As a sidenote, shellcheck reports 2 errors in your script:

$ ~/.cabal/bin/shellcheck action

In action line 5:
    echo "#"$(date)"(success)" >> ./actions
            ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
            ^-- SC2046: Quote this to prevent word splitting.


In action line 13:
    echo "#"$(date)"(failed)" >> ./actions
            ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
            ^-- SC2046: Quote this to prevent word splitting.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.