I sometimes have quite a big range of tabs open in Firefox and I prefer it to save them to a file, rather then using the build-in bookmarks.

Therefore I (manually) copy the urls from the about:preferences page, save them to a file and process the file with: tr '|' '\n' in a little bash script.

Later when I want to reopen the tabs from the textfile I run this little loop:


# usage: $bash Open-tabs.sh file-with-bookmarks.txt

 while read -r line; do
     firefox -new-tab "$line" 2>/dev/null &
     sleep 2
 done < "$1"

and it opens all tabs with a delay of 2 seconds.

I would like to know if there is a way, I can read-out the urls of the opened tabs from the command line, so I could include it to my script?


Source(Changed file path) : Get all the open tabs

This snippet gets the current firefox tab url's. It uses the recovery.js[onlz4] file in your profile folder. That file is updated almost instantly, however it will not always be the correct url.

Get all the open tabs:

python -c '
import io, json, pathlib as p
fpath = next(iter(p.Path("~/.mozilla/firefox").expanduser().glob("*.default/sessionstore-backups/recovery.js*")))
with io.open(fpath, "rb") as fd:
    if fpath.suffix == ".jsonlz4":
        import lz4.block as lz4
        fd.read(8)  # b"mozLz40\0"
        jdata = json.loads(lz4.decompress(fd.read()).decode("utf-8"))
        jdata = json.load(fd)
    for win in jdata.get("windows"):
        for tab in win.get("tabs"):
            i = tab["index"] - 1
  • is it possible, the path on debian is ~/.mozilla/firefox/*.default/sessionstore-backups/recovery.js? – nath Aug 9 '17 at 18:48
  • Yes sorry I edited the question with that but I forgot the sessionrestore-backups before recovery.js. Thank you for pointing it out. Edited Answer – Hunter.S.Thompson Aug 9 '17 at 18:49
  • I always get Traceback (most recent call last): File "<stdin>", line 2, in <module> IOError: [Errno 2] No such file or directory: '~/.mozilla/firefox/*.default/sessionstore-backups/recovery.js' with cat I can read the file... – nath Aug 9 '17 at 19:15
  • I edited the answer. copy and paste it, but instead of <username> add your username. – Hunter.S.Thompson Aug 9 '17 at 19:17
  • Python probably does not understand the ~/ syntax being /home/<username>. – Hunter.S.Thompson Aug 9 '17 at 19:19

this works for Firefox 57+. You'll need lz4 (via pip). The file header is gathered from the length of b'mozLz40\0'. Use an environment variable for the filepath if you want to use it in a oneliner, replace with \n and \t accordingly and merge lines.

export opentabs=$(find ~/.mozilla/firefox*/*.default/sessionstore-backups/recovery.jsonlz4);

python3 <<< $'import os, json, lz4.block
f = open(os.environ["opentabs"], "rb")
magic = f.read(8)
jdata = json.loads(lz4.block.decompress(f.read()).decode("utf-8"))
for win in jdata["windows"]:
    for tab in win["tabs"]:
        i = int(tab["index"]) - 1
        urls = tab["entries"][i]["url"]
  • To get the latest needed file from firefox : export opentabs=$(ls -t ~/.mozilla/firefox*/*/sessionstore-backups/recovery.jsonlz4 | sed q) – Gilles Quenot Jan 4 '18 at 0:26
  • Can you explain magic = f.read(8) ? You don't use magic var later. – Gilles Quenot Jan 4 '18 at 12:19
  • 1
    the first 8 bytes in recovery.jsonlz4 are part of mozillas custom file format - passing the length of the magic to read(8) causes the next read() within json.loads to continue after the header, making it a valid decompressable lz4 stream. For the reasoning to choose a custom file header, you can find more details in this github gist linking to the relevant firefox source. – wbob Jan 6 '18 at 11:11
  • @wbob Now I get UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf2 in position 12: invalid continuation byte, can you help ? – SebMa Jun 14 '18 at 17:22
  • @Sebma I updated to lz4 2.0.0 and got the error too, your edit fixed it, thank you. I went ahead and merged the module imports – wbob Jun 20 '18 at 19:25

Some of these answers reference the "[random chars].default" directory. Starting with version 67, users can have profiles for different update channels (e.g., release, beta, nightly, etc.).

On my Ubuntu 18 system, this directory was "[random chars].default-release". I still had a "[...].default" directory but it was mostly empty. Keep that in mind if you get an error that "sessionstore-backups" can't be found.


I recommend using https://github.com/balta2ar/brotab for this purpose:

pip install brotab
brotab install

Install the web extension as well: https://addons.mozilla.org/en-US/firefox/addon/brotab/

Restart Firefox, and you can use brotab list and parse it as so:

bt list | awk -F'\t' '{
    print "Downloading "$2
    system("curl --silent --output \""$2"\" \""$3"\"")

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.