3

I'm making a shell script to limit the amount of time someone spends on a program but it gives me these errors:

./time_limit: line 26: $Log: ambiguous redirect
./time_limit: line 16: [: root: unary operator expected

Here is the code:

#!/bin/bash
config (){
ImageViewer=/ 2> /dev/null 
AllowedTime=30 #in minutes
AllowedPlays=1
cmd=sol #for demonstration, I use sol installed by default in Ubuntu. Set to your liking
AllowedUser=root #Set to your liking.
ImageViewer=eog #I set this to the Eye of GNOME image viewer. If no GUI or if you don't want an explosion (really?) comment out.
#If you have another desktop change to yor image viewer.
Log=/dev/null #if you want to log this, set to file of your liking
#but make sure you have write permission.
config
date=$(date)

}
if [ $USER = $AllowedUser ]
then 
    echo "ACSESS ALLOWED for $AllowedTime minutes."
        at now + $AllowedTime minutes <<< "killall $cmd; $ImageViewer ../files/Explode.gif"
    echo "Session 1: $date" >> $Log
    $cmd
    exit
fi
echo "ACSESS DENIED!"
echo "This UNAUTHORIZED USE has ben recorded."
echo "Violation by $USER $date" >> $Log

I ran it though ShellCheck and it seems fine. Can anyone see the problem?

4
  • 4
    I refuse to believe shellcheck didn't warn you about quoting your variables.
    – jesse_b
    Jun 20 at 15:45
  • 1
    @jesse_b, it doesn't seem to, actually. It does mention the one where $USER isn't quoted, but not the ones about $Log. I think what happens is that it sees the constant assignment Log=/dev/null, and figures that's safe even if unquoted. But it doesn't realize the function with that assignment never runs... Comment out the assignment, and it complains about using an unset variable, and reminds about quoting it. For once, not a straight missing quotes issue :)
    – ilkkachu
    Jun 20 at 19:10
  • note that the code here does seem to call config but it does that from within the function itself. If the function was ever called in that form, it'd nest the function call endlessly, and e.g. Bash just crashes if you do that... (zsh and ksh seem smart enough to just detect and complain about recursing too deep without crashing)
    – ilkkachu
    Jun 20 at 19:16
  • Please don't add "solved", "resolved", etc. to the question.
    – muru
    Jun 21 at 3:46

1 Answer 1

5

Your config() function is never actually called in this snippet, so it will never be executed; therefore, those variables are never set. I think you meant to but accidentally put the call to config within config itself, making it an infinitely recursive function.

You need to call config, but you should also quote all your variables.

$ unset foo
$ [ $USER = $foo ]
-bash: [: jesse_b: unary operator expected
$ [ "$USER" = "$foo" ]
$ echo foo >> $foo
-bash: $foo: ambiguous redirect
$ echo foo >> "$foo"
-bash: : No such file or directory

Note that the redirection to the unset variable $foo in the example above provokes the "ambiguous redirect" error from the shell when the variable is unquoted. The solution is to make sure that the variable is set (by correctly calling config in your case), and to additionally quote all the expansions.

Setting the nounset option with set -o nounset or set -u (or adding -u option to sh / bash in the shebang) can also help identify the cases where variables are being expanded when not initialised.

Properly indenting your script would also have helped spot the problem here.

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.