last day (14 days later) » 

10:24
@terdon hi
@Elad Hi
So, why would you need to replace anything?
The $0 is the name of the script. That's a special shell variable and, no matter what your script, $0 will always be the path to it.
@terdon but there is no $0 in the syntax. it's "${0##*/}"
@Elad Sure there is. Right before the first #
@Elad I don't see $0 I see ${0
@terdon I don't see $0 I see ${0
@Elad Yes, $var and ${var} are the same thing.
In this case, we are using the shells text replacement capabilities to change the variable.
10:27
@terdon so it should be ${abcd.sh} ?
No, it should be exactly as it is: ${0##*/}
The general format is ${var##pattern} which will remove pattern from the beginning of the string.
For example:
@terdon ${abcd.sh##*/}
@Elad No, ${0##*/}
Here, look at this example:
@terdon can you give an example with an actual file name? I don't understand the syntax
$ var="foobar"
$ echo ${var}
foobar
$ echo ${var##foo}
bar
@Elad The file name is automatically saved as $0 in your script. You don't need to change anything at all.
10:29
@terdon so jsut run it as it is?
In the example above, the variable $var has the value foobar. If I then echo ${var##foo} (which means "the value of the variable $var after removing the string foo from the beginning), I get bar
@Elad Yep. The $0 is a special variable that always holds the name of the current script. Well, the path to the current script anyway. Here, consider this script:
#!/bin/bash
echo "\$0 is $0"
echo "\${0##*/} is ${0##*/}"
I have saved it as foo.sh:
@terdon Ok. Ill test it now
$ foo.sh
$0 is /home/terdon/scripts/foo.sh
${0##*/} is foo.sh
Now, I rename it to bar.sh:
@terdon just for my kownledge what -gt 1 means?
cp ~/scripts/foo.sh ~/scripts/bar.sh
And run it again:
$ bar.sh
$0 is /home/terdon/scripts/bar.sh
${0##*/} is bar.sh
See? Same script, same code, but the value of $0 changes.
@Elad "greater than". It's a numerical operator. You have -gt, -ge (greater than or equal) and similarly -lt ("less than"), -le (less than or equal) and -eq (equal)
10:35
@terdon OK. the file name is ok but the script doesn't work. It doesn't recognize that another instance is running. I opened two consoles and ran it
@Elad don't look at FreeBSD manuals, there will often be differences if you're using Linux.
@Elad OK, can you show me the exact code you ran?
@terdon Copy paste from your code. didn't change anything. Just after ur code I run my SQL comand... It should do EXIT if it found another instance running
@Elad Why would an SQL command exit? Was it the exact same shell script running twice?
Look, the trick (and what you asked for in your question) is to make a shell script exit if another copy of the same shell script is running. If you go and run the SQL command without the script, it won't work.
@terdon The SQL is the command my script suppos to run. I want it to run it only if there is no other instance of the script running. What happens after ur IF is just the regular operation of my script
@Elad The script won't stop the same SQL command from running, it will stop another copy of the script from running.
If you instead run the SQL command manually, of course that will run.
10:38
@terdon You missundestod. My script is: if [ $(pgrep -c "${0##*/}") -gt 1 ]; then
echo "Another instance of the script is running. Aborting."
exit
fi SQL COMMAND.
OK. And you ran two of those?
@terdon The SQL should happen when the IF is false. IF it's true the exit after echo should stop the script.
Yes
@terdon I opened two consoles.. ran it once.. and while it's running I ran it again.
How long does the SQL command take? Are you sure it was still running when you launched the second instance?
10:40
@terdon I'm sure because I see on colsole when it's done...
OK, hang on, let's take this to another room so we don't hijack this one. Gimme a sec.
@terdon You can test it with sleep... instad of my SQL command you can use sleep for 5 minutes...
@Elad I know. I already have and it works.
54 messages moved from Ask Ubuntu General Room
OK. So, can you try this please:
#!/bin/bash
if [ $(pgrep -c "${0##*/}") -gt 1 ]; then
     echo "Another instance of the script is running. Aborting."
     exit
fi
sleep 10
yes just a second
Then run it twice and tell me what happens. On my system:
$ foo.sh &
[1] 19072
$ foo.sh
Another instance of the script is running. Aborting.
10:45
both run at the same time
im using ubuntu 12 could this be related?
No. There's something else going on. OK, can you run this please:
#!/bin/bash
if [ $(pgrep -c "${0##*/}") -gt 1 ]; then
     echo "Another instance of the script is running. Aborting."
     exit
fi
else
    echo "PP: ${0##*/} : $(pgrep -c ${0##*/})"
fi
I should note that the pgrep always give me 0
@Elad Yes, that's what I expect.
Oh hang on.
You're running the script as bash scriptName.sh right?
it doesn't matter if another one is running pgrep always give 0
And not just scriptName.sh?
10:47
no bash... just the scriptname.sh
OK, can you run the one above then?
I need to see the output of the PP line
I just made a small correction, that should be PP: ${0##*/} and not PP: $${0##*/}
Argh.
Sorry, I'm being dense
Syntax error. Give me a sec
yes syntax error
OK, please run this:
#!/bin/bash
printf "0: %s\n" "$0"
ps aux | grep "$0"
I removed also the fi
I got 0 in the result
Yes, please run the one above
10:52
remove the last and run this?
Yes
That will show me i) the value of $0 and ii) what name the script runs under. It should help us figure out why it's not found by pgrep
sec
root 20722 0.0 0.0 9360 620 pts/0 S+ 13:52 0:00 grep /scripts/syncpoallocation
I need all the output.
this is the output
???
You should see something like this:
$ foo.sh
0: /home/terdon/scripts/foo.sh
terdon   22749  0.0  0.0  14948  2796 pts/6    S+   13:50   0:00 /bin/sh /home/terdon/scripts/foo.sh
terdon   22751  0.0  0.0  12020  2244 pts/6    R+   13:50   0:00 grep /home/terdon/scripts/foo.sh
10:55
this is what it give.. it doesn't seem to be running
You are only showing me the last line of output.
ok now it shows more:
0: /scripts/syncpoallocation
root 21623 0.0 0.0 4404 612 ? Ss 13:56 0:00 /bin/sh -c /scripts/syncpoallocation 1>/dev/null 2>/dev/null
root 21624 0.0 0.0 4404 612 ? S 13:56 0:00 /bin/sh /scripts/syncpoallocation
root 21640 0.0 0.0 9360 620 pts/0 S+ 13:56 0:00 grep /scripts/syncpoallocation
"${0##*/}" is ok. it shows what you said. $0 is also ok
I tried to re run it.. now also just one line: 0: /scripts/syncpoallocation
root 21672 0.0 0.0 9360 616 pts/0 S+ 13:57 0:00 grep /scripts/syncpoallocation
HOw are you running it? What exact command are you using?
/scripts/syncpoallocation
And you changed the #!/bin/bash I told you to #/bin/sh
Even so, it should work.
But please run it again exactly as I showed it so with #!/bin/bash as the first line and not #!/bin/sh
11:01
in both cases it doesn't work :(
sec
This? #/bin/sh printf "0: %s\n" "$0"
ps aux | grep "$0"
@Elad No. You changed it to sh instead of bash again
#!/bin/bash
printf "0: %s\n" "$0"
ps aux | grep "$0"
it's not running
this is what i get:
any ideas?
@Elad Depends, what do you get? You haven't shown me.
11:10
I did...
0: /scripts/syncpoallocation
root 23678 0.0 0.0 9360 620 pts/0 S+ 14:04 0:00 grep /scripts/syncpoallocation
This is the returned value. The script is not ruuning with this command
If it isn't running, how do you get output?
Oh hang on. Please tell me you are not using a Windows machine to connect to Ubuntu
No, Ubuntu directly
And you're not editing anything on Windows?
No windows involved.
Say I want to print to colnsole the number of scrips running (with this name) something like: print number, sleep 1000 If i'll run it 3 time I should see 0 then 1 then 2 right?
No. You should never see 0.
That's the problem.
OK, one more try. Run this and show me the output:
#!/bin/bash
printf "0: %s\nCut: %s\n" "$0" "${0##*/}"
ps aux | grep "$0"
echo "P1: $(pgrep ${0##*/})"
echo "P2: $(pgrep -f  ${0##*/})"
11:17
sec
0: /scripts/syncpoallocation.sh
Cut: syncpoallocation.sh
root 25884 0.0 0.0 9360 616 pts/1 S+ 14:17 0:00 grep /scripts/syncpoallocation.sh
P1:
P2:
OK, no, that's just impossible :)
Makes no sense. One more try:
#!/bin/bash
printf "0: %s\nCut: %s\n" "$0" "${0##*/}"
ps aux | grep "syncpoallocation"
When I do:
#!/bin/bash
printf "0: %s\nCut: %s\n" "$0" "${0##*/}"
echo $0
echo ${0##*/}
ps aux | grep "$0"
echo "P1: $(pgrep ${0##*/})"
echo "P2: $(pgrep -f ${0##*/})"
I get:
0: /scripts/syncpoallocation.sh
Cut: syncpoallocation.sh
/scripts/syncpoallocation.sh
syncpoallocation.sh
root 26169 0.0 0.0 9360 620 pts/1 S+ 14:19 0:00 grep /scripts/syncpoallocation.sh
P1:
P2:
@Elad Yes, and that makes no sense at all. The ps aux | grep $0 should have two results, not one. Which is why I asked you to run it again but searching explicitly for syncpoallocation
Ah, no, even better. Try this:
#!/bin/bash
ps aux | grep "$$"
I think I know what may cause it
@Elad Oh?
11:23
when the script is running.. I don't see it on ps aux it's like it doesn't exists
I know. That's what's so weird.
Try what I gave you above. That will search for $$ (the script's process id).
#!/bin/bash
ps aux | grep "$$"
@Elad?
sec
root 28772 0.0 0.0 12320 1380 pts/0 S+ 14:29 0:00 /bin/bash /scripts/syncpoallocation.sh
root 28774 0.0 0.0 9360 616 pts/0 S+ 14:29 0:00 grep 28772
Argh! That makes no sense! There's the script, running normally, so why isn't it shown when we grep for it?
Could this be a bug in the operating system?
11:32
my ubuntu is old (12)
This hasn't changed since long before Linux was even created.
Could there be some sort of strange character in the script's name? Try this:
#!/bin/bash
ps aux | grep "$$" | grep -v grep | od -c
it's regular english letters...
Te output will be several weird looking lines. Just paste them here
@Elad I know. I'm clutching at straws here. There might be a non-printing character in there and this should show it.
root@pg-production01:~# /scripts/syncpoallocation.sh
0000000 r o o t 2 9 7 7 4
0000020 0 . 0 0 . 0 2 3 3 1 2
0000040 3 5 4 8 p t s / 0 S
0000060 + 1 4 : 3 4 0 : 0 0
0000100 - b a s h \n
0000107
OK.
So it looks like it's only showing the script as "bash" and not "bash scriptName.sh"
11:37
what is that means?
@Elad Nothing, it's a trick that will show you each character. Note the \n at the end, that's a newline which is normally invisible. The point is that the script name isn't included, it only shows bash for some reason.
And that's why it doesn't work when we search for the script name
How do I solve it?
OK, forget it then, use the second approach with the lock file:
Add this to the beginning of the real script:
if [ -e "/tmp/i.am.running" ]; then
    echo "Another instance of the script is running. Aborting."
    exit
fi
else
    touch  "/tmp/i.am.running"
fi
(you might want to change i.am.running to syncpoallocation.running or something. But it's up to you. )
Then, add this to the end of the script:
I prefer not to do it with file locks.. :(
Yeah. I can understand that.
But if your system is behaving in this weird way, I don't know how to get around it.
11:40
I think i'll wait till we upgrade to ubuntu 14 maybe it will be resolved on itself
I doubt it. It's really odd.
What in the world are you doing on Ubuntu 12 anyway?
Oh, and are you really doing this logged in as root on a production system?
If I were your boss, I'd have probably fired you now.
You never, ever test commands given by random strangers on the internet as root and NEVER as root on a production system!
our last upgrade was at 2014. Since ubuntu also upgrades packages like python etc.. we can not "just upgrade it".... it effects everything in our system... it takes about 4-5 months to check everything works with the new OS
Seriously. Don't ever do that again.
I might have given you a command that would break the system. Either because I'm malicious or just by mistake. Never test things as root.
(sorry, rant over, I couldn't help myself)
it's not our root production.. it's just called this way :) it's a server which used to be production but not used anymore
Ah, phew
I feel better now :)
11:43
lol... it took me a while to respond to use because i double checked your instructions.. even when it's test server i double check :)
Good! You wouldn't believe how many idiots users break their systems this way.
Let's test one more thing. Run these commands and tell me their output:
file /bin/bash
/bin/bash --version
type -a bash
sec
4.2.24 (1)-release
And file /bin/bash tells you it's an ELF executable, right?
11:59
I have to go to a meeting so I won't be able to contine... Thank you so much for your time... I'll try to look for more solutions :)
@Elad You're welcome and sorry I couldn't be more help. I suggest you ask a new question but on Unix & Linux (your version of Ubuntu is off topic here). Give one of the really simple scripts we tried here and the output of ps and ask why ps only shows bash and not the name of the script.
If we can figure that out, the rest should be easy.
will do. thank you :)
@Elad Let me know if you do, please. I'm curious now :)

last day (14 days later) »