Shell Script while loop: [ around a pipeline missing `]'












4















The shell script I'm trying to use keeps giving this error:



$ ./script.sh: line 2: [: missing `]' 
grep: ]: No such file or directory


The line is part of a section trying to check if a particular process is going to have a file locked:



COUNTER=0
while [ ps aux | grep "[r]elayevent.sh" ] && [ "$COUNTER" -lt 10 ]; do
sleep 3
let COUNTER+=1
done


Obviously I've checked that the brackets all pair up correctly - which looks fine to me. Also the common white space around the condition issue doesn't apply.



What am I missing here?










share|improve this question




















  • 2





    Note for the future. Whenever you get a syntax error, run - don't walk - straight to shellcheck.net and paste in the block of your code that exhibits the issue.

    – roaima
    Feb 6 at 8:37











  • You should use flock command to implement locks in scripts.

    – dnt
    Feb 6 at 10:03


















4















The shell script I'm trying to use keeps giving this error:



$ ./script.sh: line 2: [: missing `]' 
grep: ]: No such file or directory


The line is part of a section trying to check if a particular process is going to have a file locked:



COUNTER=0
while [ ps aux | grep "[r]elayevent.sh" ] && [ "$COUNTER" -lt 10 ]; do
sleep 3
let COUNTER+=1
done


Obviously I've checked that the brackets all pair up correctly - which looks fine to me. Also the common white space around the condition issue doesn't apply.



What am I missing here?










share|improve this question




















  • 2





    Note for the future. Whenever you get a syntax error, run - don't walk - straight to shellcheck.net and paste in the block of your code that exhibits the issue.

    – roaima
    Feb 6 at 8:37











  • You should use flock command to implement locks in scripts.

    – dnt
    Feb 6 at 10:03
















4












4








4








The shell script I'm trying to use keeps giving this error:



$ ./script.sh: line 2: [: missing `]' 
grep: ]: No such file or directory


The line is part of a section trying to check if a particular process is going to have a file locked:



COUNTER=0
while [ ps aux | grep "[r]elayevent.sh" ] && [ "$COUNTER" -lt 10 ]; do
sleep 3
let COUNTER+=1
done


Obviously I've checked that the brackets all pair up correctly - which looks fine to me. Also the common white space around the condition issue doesn't apply.



What am I missing here?










share|improve this question
















The shell script I'm trying to use keeps giving this error:



$ ./script.sh: line 2: [: missing `]' 
grep: ]: No such file or directory


The line is part of a section trying to check if a particular process is going to have a file locked:



COUNTER=0
while [ ps aux | grep "[r]elayevent.sh" ] && [ "$COUNTER" -lt 10 ]; do
sleep 3
let COUNTER+=1
done


Obviously I've checked that the brackets all pair up correctly - which looks fine to me. Also the common white space around the condition issue doesn't apply.



What am I missing here?







linux shell-script scripting






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 20 hours ago









PRY

2,23031025




2,23031025










asked Feb 6 at 3:32









Kiwi CamKiwi Cam

293




293








  • 2





    Note for the future. Whenever you get a syntax error, run - don't walk - straight to shellcheck.net and paste in the block of your code that exhibits the issue.

    – roaima
    Feb 6 at 8:37











  • You should use flock command to implement locks in scripts.

    – dnt
    Feb 6 at 10:03
















  • 2





    Note for the future. Whenever you get a syntax error, run - don't walk - straight to shellcheck.net and paste in the block of your code that exhibits the issue.

    – roaima
    Feb 6 at 8:37











  • You should use flock command to implement locks in scripts.

    – dnt
    Feb 6 at 10:03










2




2





Note for the future. Whenever you get a syntax error, run - don't walk - straight to shellcheck.net and paste in the block of your code that exhibits the issue.

– roaima
Feb 6 at 8:37





Note for the future. Whenever you get a syntax error, run - don't walk - straight to shellcheck.net and paste in the block of your code that exhibits the issue.

– roaima
Feb 6 at 8:37













You should use flock command to implement locks in scripts.

– dnt
Feb 6 at 10:03







You should use flock command to implement locks in scripts.

– dnt
Feb 6 at 10:03












2 Answers
2






active

oldest

votes


















7














The error is that you should remove first [ because of you want to check the exit status then use command directly.



The Wiki pages of the Shellcheck tool have an explanation for this (issue SC1014):




[ .. ] is not part of shell syntax like if statements. It is not equivalent to parentheses in C-like languages, if (foo) { bar; }, and should not be wrapped around commands to test.



[ is just regular command, like whoami or grep, but with a funny name (see ls -l /bin/[). It's a shorthand for test.



If you want to check the exit status of a certain command, use that command directly.



If you want to check the output of a command, use "$(..)" to get its output, and then use test or [/[[ to do a string comparison:




Also use ps aux | grep -q "[r]elayevent.sh" so that you will get the exit status silently instead of printing anything to stdout.



Or you can use pgrep and direct it's output to /dev/null.



Use second condition first because it will be more efficient for the last case.



So final script will be like:



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do

sleep 3

let COUNTER+=1

done


Or



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do

sleep 3

let COUNTER+=1

done





share|improve this answer





















  • 4





    You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

    – Mikel
    Feb 6 at 4:21













  • @Mikel thanks, it will silently give status instead of printing anything.

    – PRY
    Feb 6 at 4:25











  • You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

    – mosvy
    Feb 6 at 4:59








  • 1





    I would swap the tests around to avoid running grep on the last iteration.

    – Kusalananda
    Feb 6 at 7:31











  • That is more efficient.

    – PRY
    Feb 6 at 7:49



















2














You can't have a pipe inside [ ... ]. It's also better to use pgrep than to try to parse the output of ps:



count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done


BSD systems could use pgrep -q ... instead of pgrep ... >/dev/null to discard the actual output of pgrep, just as with ordinary grep (we're only interested in the exit status).



Note how we don't put the pgrep command within [ ... ]. That's because we're not interested in its output, only its exit status. With [ ... ] you commonly compare strings or numbers. The [ ... ] will result in an exit status that is zero (true) or non-zero (false), just like the pgrep execution.



However, this does not check for any locking mechanisms, only whether a particular process is running or not.



If you are trying to get only a single instance of a script running, then it's better to do something like this (assuming the EXIT trap is executed whenever the script is terminating orderly):



lockdir=dir.lock

if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi


With a number of tries and sleep:



lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
break
else
echo 'Locked. Sleeping...' >&2
sleep 3
fi

count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
echo 'Giving up.' >&2
exit 1
fi


Related:




  • How to make sure only one instance of a bash script runs?






share|improve this answer


























  • I also thought of pgrep but didn't thought of /dev/null.

    – PRY
    Feb 6 at 8:43











  • @PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

    – Kusalananda
    Feb 6 at 8:46











  • @PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

    – Uncle Billy
    Feb 6 at 8:46













Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f498953%2fshell-script-while-loop-around-a-pipeline-missing%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









7














The error is that you should remove first [ because of you want to check the exit status then use command directly.



The Wiki pages of the Shellcheck tool have an explanation for this (issue SC1014):




[ .. ] is not part of shell syntax like if statements. It is not equivalent to parentheses in C-like languages, if (foo) { bar; }, and should not be wrapped around commands to test.



[ is just regular command, like whoami or grep, but with a funny name (see ls -l /bin/[). It's a shorthand for test.



If you want to check the exit status of a certain command, use that command directly.



If you want to check the output of a command, use "$(..)" to get its output, and then use test or [/[[ to do a string comparison:




Also use ps aux | grep -q "[r]elayevent.sh" so that you will get the exit status silently instead of printing anything to stdout.



Or you can use pgrep and direct it's output to /dev/null.



Use second condition first because it will be more efficient for the last case.



So final script will be like:



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do

sleep 3

let COUNTER+=1

done


Or



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do

sleep 3

let COUNTER+=1

done





share|improve this answer





















  • 4





    You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

    – Mikel
    Feb 6 at 4:21













  • @Mikel thanks, it will silently give status instead of printing anything.

    – PRY
    Feb 6 at 4:25











  • You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

    – mosvy
    Feb 6 at 4:59








  • 1





    I would swap the tests around to avoid running grep on the last iteration.

    – Kusalananda
    Feb 6 at 7:31











  • That is more efficient.

    – PRY
    Feb 6 at 7:49
















7














The error is that you should remove first [ because of you want to check the exit status then use command directly.



The Wiki pages of the Shellcheck tool have an explanation for this (issue SC1014):




[ .. ] is not part of shell syntax like if statements. It is not equivalent to parentheses in C-like languages, if (foo) { bar; }, and should not be wrapped around commands to test.



[ is just regular command, like whoami or grep, but with a funny name (see ls -l /bin/[). It's a shorthand for test.



If you want to check the exit status of a certain command, use that command directly.



If you want to check the output of a command, use "$(..)" to get its output, and then use test or [/[[ to do a string comparison:




Also use ps aux | grep -q "[r]elayevent.sh" so that you will get the exit status silently instead of printing anything to stdout.



Or you can use pgrep and direct it's output to /dev/null.



Use second condition first because it will be more efficient for the last case.



So final script will be like:



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do

sleep 3

let COUNTER+=1

done


Or



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do

sleep 3

let COUNTER+=1

done





share|improve this answer





















  • 4





    You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

    – Mikel
    Feb 6 at 4:21













  • @Mikel thanks, it will silently give status instead of printing anything.

    – PRY
    Feb 6 at 4:25











  • You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

    – mosvy
    Feb 6 at 4:59








  • 1





    I would swap the tests around to avoid running grep on the last iteration.

    – Kusalananda
    Feb 6 at 7:31











  • That is more efficient.

    – PRY
    Feb 6 at 7:49














7












7








7







The error is that you should remove first [ because of you want to check the exit status then use command directly.



The Wiki pages of the Shellcheck tool have an explanation for this (issue SC1014):




[ .. ] is not part of shell syntax like if statements. It is not equivalent to parentheses in C-like languages, if (foo) { bar; }, and should not be wrapped around commands to test.



[ is just regular command, like whoami or grep, but with a funny name (see ls -l /bin/[). It's a shorthand for test.



If you want to check the exit status of a certain command, use that command directly.



If you want to check the output of a command, use "$(..)" to get its output, and then use test or [/[[ to do a string comparison:




Also use ps aux | grep -q "[r]elayevent.sh" so that you will get the exit status silently instead of printing anything to stdout.



Or you can use pgrep and direct it's output to /dev/null.



Use second condition first because it will be more efficient for the last case.



So final script will be like:



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do

sleep 3

let COUNTER+=1

done


Or



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do

sleep 3

let COUNTER+=1

done





share|improve this answer















The error is that you should remove first [ because of you want to check the exit status then use command directly.



The Wiki pages of the Shellcheck tool have an explanation for this (issue SC1014):




[ .. ] is not part of shell syntax like if statements. It is not equivalent to parentheses in C-like languages, if (foo) { bar; }, and should not be wrapped around commands to test.



[ is just regular command, like whoami or grep, but with a funny name (see ls -l /bin/[). It's a shorthand for test.



If you want to check the exit status of a certain command, use that command directly.



If you want to check the output of a command, use "$(..)" to get its output, and then use test or [/[[ to do a string comparison:




Also use ps aux | grep -q "[r]elayevent.sh" so that you will get the exit status silently instead of printing anything to stdout.



Or you can use pgrep and direct it's output to /dev/null.



Use second condition first because it will be more efficient for the last case.



So final script will be like:



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do

sleep 3

let COUNTER+=1

done


Or



#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do

sleep 3

let COUNTER+=1

done






share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 6 at 13:28









ilkkachu

58.7k892165




58.7k892165










answered Feb 6 at 4:02









PRYPRY

2,23031025




2,23031025








  • 4





    You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

    – Mikel
    Feb 6 at 4:21













  • @Mikel thanks, it will silently give status instead of printing anything.

    – PRY
    Feb 6 at 4:25











  • You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

    – mosvy
    Feb 6 at 4:59








  • 1





    I would swap the tests around to avoid running grep on the last iteration.

    – Kusalananda
    Feb 6 at 7:31











  • That is more efficient.

    – PRY
    Feb 6 at 7:49














  • 4





    You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

    – Mikel
    Feb 6 at 4:21













  • @Mikel thanks, it will silently give status instead of printing anything.

    – PRY
    Feb 6 at 4:25











  • You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

    – mosvy
    Feb 6 at 4:59








  • 1





    I would swap the tests around to avoid running grep on the last iteration.

    – Kusalananda
    Feb 6 at 7:31











  • That is more efficient.

    – PRY
    Feb 6 at 7:49








4




4





You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

– Mikel
Feb 6 at 4:21







You probably want to add -q when calling grep, too. Otherwise it prints the matching lines.

– Mikel
Feb 6 at 4:21















@Mikel thanks, it will silently give status instead of printing anything.

– PRY
Feb 6 at 4:25





@Mikel thanks, it will silently give status instead of printing anything.

– PRY
Feb 6 at 4:25













You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

– mosvy
Feb 6 at 4:59







You should mention where that quote is from. Also, grep -q "[r]elayevent.sh" doesn't make much sense, and ps | grep is usually better replaced with pgrep; but the let COUNTER+=1 is fine in bash, zsh and ksh39 (((..)) is not a bit more portable) -- though the whole script doesn't make much sense ;-)).

– mosvy
Feb 6 at 4:59






1




1





I would swap the tests around to avoid running grep on the last iteration.

– Kusalananda
Feb 6 at 7:31





I would swap the tests around to avoid running grep on the last iteration.

– Kusalananda
Feb 6 at 7:31













That is more efficient.

– PRY
Feb 6 at 7:49





That is more efficient.

– PRY
Feb 6 at 7:49













2














You can't have a pipe inside [ ... ]. It's also better to use pgrep than to try to parse the output of ps:



count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done


BSD systems could use pgrep -q ... instead of pgrep ... >/dev/null to discard the actual output of pgrep, just as with ordinary grep (we're only interested in the exit status).



Note how we don't put the pgrep command within [ ... ]. That's because we're not interested in its output, only its exit status. With [ ... ] you commonly compare strings or numbers. The [ ... ] will result in an exit status that is zero (true) or non-zero (false), just like the pgrep execution.



However, this does not check for any locking mechanisms, only whether a particular process is running or not.



If you are trying to get only a single instance of a script running, then it's better to do something like this (assuming the EXIT trap is executed whenever the script is terminating orderly):



lockdir=dir.lock

if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi


With a number of tries and sleep:



lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
break
else
echo 'Locked. Sleeping...' >&2
sleep 3
fi

count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
echo 'Giving up.' >&2
exit 1
fi


Related:




  • How to make sure only one instance of a bash script runs?






share|improve this answer


























  • I also thought of pgrep but didn't thought of /dev/null.

    – PRY
    Feb 6 at 8:43











  • @PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

    – Kusalananda
    Feb 6 at 8:46











  • @PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

    – Uncle Billy
    Feb 6 at 8:46


















2














You can't have a pipe inside [ ... ]. It's also better to use pgrep than to try to parse the output of ps:



count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done


BSD systems could use pgrep -q ... instead of pgrep ... >/dev/null to discard the actual output of pgrep, just as with ordinary grep (we're only interested in the exit status).



Note how we don't put the pgrep command within [ ... ]. That's because we're not interested in its output, only its exit status. With [ ... ] you commonly compare strings or numbers. The [ ... ] will result in an exit status that is zero (true) or non-zero (false), just like the pgrep execution.



However, this does not check for any locking mechanisms, only whether a particular process is running or not.



If you are trying to get only a single instance of a script running, then it's better to do something like this (assuming the EXIT trap is executed whenever the script is terminating orderly):



lockdir=dir.lock

if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi


With a number of tries and sleep:



lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
break
else
echo 'Locked. Sleeping...' >&2
sleep 3
fi

count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
echo 'Giving up.' >&2
exit 1
fi


Related:




  • How to make sure only one instance of a bash script runs?






share|improve this answer


























  • I also thought of pgrep but didn't thought of /dev/null.

    – PRY
    Feb 6 at 8:43











  • @PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

    – Kusalananda
    Feb 6 at 8:46











  • @PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

    – Uncle Billy
    Feb 6 at 8:46
















2












2








2







You can't have a pipe inside [ ... ]. It's also better to use pgrep than to try to parse the output of ps:



count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done


BSD systems could use pgrep -q ... instead of pgrep ... >/dev/null to discard the actual output of pgrep, just as with ordinary grep (we're only interested in the exit status).



Note how we don't put the pgrep command within [ ... ]. That's because we're not interested in its output, only its exit status. With [ ... ] you commonly compare strings or numbers. The [ ... ] will result in an exit status that is zero (true) or non-zero (false), just like the pgrep execution.



However, this does not check for any locking mechanisms, only whether a particular process is running or not.



If you are trying to get only a single instance of a script running, then it's better to do something like this (assuming the EXIT trap is executed whenever the script is terminating orderly):



lockdir=dir.lock

if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi


With a number of tries and sleep:



lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
break
else
echo 'Locked. Sleeping...' >&2
sleep 3
fi

count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
echo 'Giving up.' >&2
exit 1
fi


Related:




  • How to make sure only one instance of a bash script runs?






share|improve this answer















You can't have a pipe inside [ ... ]. It's also better to use pgrep than to try to parse the output of ps:



count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done


BSD systems could use pgrep -q ... instead of pgrep ... >/dev/null to discard the actual output of pgrep, just as with ordinary grep (we're only interested in the exit status).



Note how we don't put the pgrep command within [ ... ]. That's because we're not interested in its output, only its exit status. With [ ... ] you commonly compare strings or numbers. The [ ... ] will result in an exit status that is zero (true) or non-zero (false), just like the pgrep execution.



However, this does not check for any locking mechanisms, only whether a particular process is running or not.



If you are trying to get only a single instance of a script running, then it's better to do something like this (assuming the EXIT trap is executed whenever the script is terminating orderly):



lockdir=dir.lock

if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi


With a number of tries and sleep:



lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
break
else
echo 'Locked. Sleeping...' >&2
sleep 3
fi

count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
echo 'Giving up.' >&2
exit 1
fi


Related:




  • How to make sure only one instance of a bash script runs?







share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 7 at 8:31

























answered Feb 6 at 8:05









KusalanandaKusalananda

129k16246404




129k16246404













  • I also thought of pgrep but didn't thought of /dev/null.

    – PRY
    Feb 6 at 8:43











  • @PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

    – Kusalananda
    Feb 6 at 8:46











  • @PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

    – Uncle Billy
    Feb 6 at 8:46





















  • I also thought of pgrep but didn't thought of /dev/null.

    – PRY
    Feb 6 at 8:43











  • @PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

    – Kusalananda
    Feb 6 at 8:46











  • @PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

    – Uncle Billy
    Feb 6 at 8:46



















I also thought of pgrep but didn't thought of /dev/null.

– PRY
Feb 6 at 8:43





I also thought of pgrep but didn't thought of /dev/null.

– PRY
Feb 6 at 8:43













@PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

– Kusalananda
Feb 6 at 8:46





@PRY pgrep on BSD systems have a -q option to avoid that particular ugliness. It works just as with grep.

– Kusalananda
Feb 6 at 8:46













@PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

– Uncle Billy
Feb 6 at 8:46







@PRY you could use pkill -0 ... instead of pgrep ... >/dev/null

– Uncle Billy
Feb 6 at 8:46




















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f498953%2fshell-script-while-loop-around-a-pipeline-missing%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to send String Array data to Server using php in android

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

Is anime1.com a legal site for watching anime?