Goal: using sudo execute a one line cmd to tail a log until a string is found and then exit 0. If the string is not found within a given timeout, exit anything but 0.
Attempted Solution 1: Originally I did not have timeout as a requirement and so after some research I landed on using:
sudo sh -c '( tail -n1 -f /path/to/nameOfLog.log & ) | grep -q "Started .*Application"'
However, now I do have timeout as a requirement. I could not figure out how to get timeout to work with this command until I found Ondra Žižka's answer. So my new cmd became:
Attempt Solution 2:
timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)
But this obviously is not using sudo permissions, which is the current issue I need to solve. Below are some variations I've tried which failed
Try 1 : (add sudo in front of cmd)
sudo timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)
Output:
grep: /dev/fd/63: No such file or directory
Try 2: (try to wrap cmd in subshell)
sudo sh -c 'timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)'
Output:
sh: 1: Syntax error: "(" unexpected
Can someone show me and explain the issue and how to fix it so I can run this command using sudo? Also, do I really need to restructure cmd from Attempted Solution 1 to get it to work with timeout as well?
Best Answer
1) I'm not sure if the subshell (or backgrounding) is useful here:
shouldn't a simple pipe do?
2) Your "try 1":
expands the input redirection
<()
on the command line that runs thesudo
, not insidesudo
. The filehandle it opens isn't passed throughsudo
togrep
, sogrep
can't open the/dev/fd/63
pseudo-file.Same thing about backgrounding the
tail
here, it shouldn't be necessary.3) And, as phk commented, your "try 2":
...explicitly runs
sh
, and notbash
or any other more featureful shell. Plain standardsh
doesn't support<()
, and neither doesdash
which is used assh
on Debian and Ubuntu.When you run
su
instead, it runsroot
's login shell, which is likely to bebash
on Ubuntu. But using bothsudo
andsu
is redundant, they're both made to elevate privileges, and aftersudo
you're already running elevated privilege, so no need forsu
. Instead, if you want to run a shell insidesudo
, just say explicitly which one: