2

I have a script that starts firefox for 4 seconds, then kills it. Firefox will automatically log into a captive portal, so I only need it to be open for 4 seconds, as soon as the wifi connects. I am on Ubuntu 13.04.

My problem seems to be that $pid isn't set.

firefox ; pid=$!
sleep 4
kill $pid

EDIT: removed set, and now it gives kill an invalid pid.

  • 2
    N.B. $! is the PID (process ID) of last job run in background, so you'd have to replace ; with & at the very least. Not that this would solve your main problem. – Cristian Ciupitu Oct 21 '13 at 17:22
  • I know that does does not answer the question, but why use firefox to log in via the captive portal? That is like going rowing with a battleship. Wget or curl are much more lightweight. (Link to curl example). – Hennes Oct 21 '13 at 18:14
  • 1
    Related: Bash Run command for certain time? – mpy Oct 21 '13 at 19:20
  • @Hennes I also wanted to login to a captive portal. Wget and curl failed for me (maybe because of javascript elements or similar things). I finally succeeded using elinks. Not as lightweight as curl or wget, but much better than firefox. – Tim Oct 23 '13 at 13:24
  • @Tim The problem here is that it has some fancy javascript that needs running so it will work. – Yet Another User Oct 23 '13 at 19:26
9

Your script does not work, because it waits until the firefox process has ended and afterwards executes pid=$!and the other command.

An easy way to do what you want is timeout:

timeout 4s firefox

It starts the program provided after the first argument and stops it after the time given as the first argument has passed.

| improve this answer | |
  • What is timeout? I don't think it is part of standard Linux installations. – jaychris Oct 21 '13 at 21:27
  • 1
    @jaychris It comes with coreutils, so it should be part of a standard installation. – Tim Oct 22 '13 at 6:12
  • It seems to be missing on my Ubuntu server. (Not the most recent Ubuntu, but apt-get easily fixed that). – Hennes Oct 23 '13 at 16:03
  • so awesome, shell scripting in Jenkins and had a show logs command that could only be control Zed to exit, except timeout, that works! – edencorbin Jun 10 '18 at 1:41
1

The reason your pid=$! fails is that $! is the PID of last job run in background.

I.e.,

$ foo & echo $!

will start foo and echo the PID of its process.

In your case, firefox ; pid=$! would need to be replaced with firefox & pid=$! but it might be pretty useless because firefox is a script which execs the actual binary.

What you need to do is either use killall (which will try to kill all the instances firefox, whether yours or other users') or (copy and) edit the /usr/bin/firefox script to echo the new PID.

| improve this answer | |
  • why downvote?.. – sds Aug 21 '14 at 13:15
0

A few more solutions.

| improve this answer | |
  • killing firefox puts it in safe mode. That is undesirable. – Yet Another User Oct 23 '13 at 19:07
-1

After following a few hints from the other answers, I came up with this messy script:

firefox -no-remote -p c-portal &
ffpid=`ps aux | grep firefox | sed '2q;d' | tr -s ' ' | cut -d ' ' -f 2`
echo "firefox pid: $ffpid"
sleep 4
kill $ffpid

I also needed to go into about:config and change browser.sessionstore.resume_from_crash to false.

Explanation of each command: ps aux gets the full list of processes on the system, grep finds all the ones containing firefox, sed gets the second line (which appears to always be the latest instance of firefox), tr removes the extra spaces, cut gets the second column (-d means delimiter, which is a space).

After that string-processing mess, there's a debug thing that prints out the PID of firefox, sleep for 4 seconds, so it can log in, then it kills firefox. The about:config setting prevents it from trying to restore the session.

| improve this answer | |
  • 1
    A handy command to get a process id is pgrep. – Dean Oct 21 '13 at 18:24
  • As Dean suggested, using pgrep firefox removes all the "string-processing mess". And really, using firefox for this is silly, slow and resource intensive. Just use curl or wget as Hennes suggested. – terdon Oct 21 '13 at 19:04
  • @terdon I HAVE tried. Their silly captive portal runs some javascript that I can't seem to reverse-engineer the POST requests for. I have looked at it using wireshark, and my attempt to make it do what it's supposed to do fails horribly. It might be checking for if the browser has visited the captive portal page before actually doing anything. – Yet Another User Oct 21 '13 at 19:32
  • Fair enough, using firefox is much easier than deciphering other people's code. – terdon Oct 21 '13 at 21:33
  • @terdon Especially when they don't really care about it being readable to others. Even more so, when they kind of don't want people reading it, as that could mess with their security. – Yet Another User Oct 23 '13 at 19:09
-2

I'm not sure if it fits your situation, but you could use killall instead of kill. So it would be:

firefox
sleep 4
killall firefox

I think a more correct approach is to get the last firefox process using ps aux | grep firefox, but today I don't know how to do that treatment of returning only that highest process number using bash script.

| improve this answer | |
  • Definitely not! Usually, I have a bunch of firefox instances running, and I don't want to kill all of them. ps aux | grep firefox does seem interesting, though. I will try it. – Yet Another User Oct 21 '13 at 16:32
  • @YetAnotherUser: you don't have a bunch of instances (processes), you have only one process displaying multiple windows and tabs. I'd suggest using a separate profile just for this, if possible. – Cristian Ciupitu Oct 21 '13 at 16:56
  • Separate profile? Hmmm yeah. I hacked together a long string of commands that gets the pid. Will post it shortly as soon as I get it completely working. – Yet Another User Oct 21 '13 at 17:08
  • Aside from the danger of killall (kill all firefoxes on Linux, kill a lot more Solaris), you might want to add a & after the firefox command. Else your sleep will not start until after you closed firefox. – Hennes Oct 23 '13 at 16:05

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.