2

I am trying to generate docsets for Dash following these instructions: http://kapeli.com/docsets. The problem is, that the script doesn't continue after the wget and doesn't appear to throw any errors. Everything works fine when I copy the script into the Terminal.

I'm using MacOS 10.8.4 and the default bash.

#!/usr/bin/env bash
set -e

mkdir -p $1.docset/Contents/Resources/Documents/

echo "THIS RUNS"
wget -rkp -l3 -np -nH --cut-dirs=1 --directory-prefix="./"$1".docset/Contents/Resources/Documents/" $2
echo "THIS DOES NOT RUN"

sed "s/NAME/$1/g" template > $1.docset/Contents/Info.plist
touch $1.docset/Contents/Resources/docSet.dsidx
# (script continues) 

I looked at other posts like My shell script stops after exec but I'm not using exec here.

Why does the script exit?

that other guy
  • 116,971
  • 11
  • 170
  • 194
JMH
  • 1,289
  • 1
  • 10
  • 19

4 Answers4

5

You enabled set -e aka errexit.

Your script will exit if one of the commands returns a non-zero exit code, and it may not always be obvious which command specifically fails:

  • Some may print a helpful error identifying itself and the problem
  • Some (like wget) may briefly mention an error way back in pagefuls of output
  • Some (like grep) may not show errors or any output at all, the script just exits

To know which command is causing a problem, run script with -x aka xtrace:

bash -x script.sh

Or add set -x to the script itself:

set -x
set -e
...

This will cause the script to print out each command being executed, so you can see which one was the last.

If you would like to ignore the exit status of a command, you can add || true:

# Causes exit if you lack read permission on any directory
find . -name '*.sh' 

# Does not cause the script to exit
find . -name '*.sh' || true

If you would like to be alerted when set -e would trigger in your script, you can set a trap:

#!/bin/bash
set -e
# Show error if commands exit with non-zero
trap 'ret=$?; echo "$0:$LINENO: Error: set -e triggered"; exit $ret' ERR
# Would have failed silently
grep doesnotexist /etc/passwd
echo "This does not run"

When executed:

$ ./foo
./foo:6: Error: set -e triggered
that other guy
  • 116,971
  • 11
  • 170
  • 194
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • Tried that, just like before it works fine until wget is done, then everthing else is simply ignored. – JMH Sep 15 '13 at 17:48
  • 1
    @basszwo You don't see others run? It's a problem with wget then. Can you add `-v` or `--verbose` option to it to see possible error messages. – konsolebox Sep 15 '13 at 17:52
  • Wget is getting quite a few 404 errors and returns exit status 8 (echo $?). The actual question is solved then, however, I still don't know what to do about it: removing "set -e" works fine but doesn't feel right. – JMH Sep 15 '13 at 18:11
  • 1
    @basszwo You should quote your variables as well to prevent word splitting which would cause your arguments and files created different. e.g. `"--directory-prefix=./$1.docset/Contents/Resources/Documents/" "$2"` – konsolebox Sep 15 '13 at 18:30
  • I suspect that `set -e` causes the $1 to be `-e`. Correct me if I'm wrong. – Max Ch Nov 19 '13 at 12:09
  • @MaxCh According to `help set`: "-e Exit immediately if a command exits with a non-zero status". If you wanted to set `$1` to `-e`, you would need to use `set -- -e` – that other guy Dec 22 '20 at 19:16
1

UPDATE

My original answer was a misunderstanding of your question. One issue that that seems to be a problem is your:

INSERT INTO searchIndex (name, type, path) VALUES (index, Guide, 'index.html');

Not sure here. But it seems like you might want to make index and Guide strings, like so:

INSERT INTO searchIndex (name, type, path) VALUES ('index', 'Guide', 'index.html');
masahji
  • 544
  • 2
  • 6
  • That's intended, the $1 (name of the docset) gets concatenated into the prefix. Is there a better (correct, non breaking) way to do this? – JMH Sep 15 '13 at 17:29
1

Try using here documents, something like this:

cat > "$1.docset/Contents/Info.plist" << EOF
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
    <key>CFBundleIdentifier</key>
    <string>$1</string>
    <key>CFBundleName</key>
    <string>$1</string>
    <key>DocSetPlatformFamily</key>
    <string>$1</string>
    <key>isDashDocset</key>
    <true/>
  </dict>
  </plist>
EOF

It is less prone to quoting errors

Scrutinizer
  • 9,608
  • 1
  • 21
  • 22
  • Thats right, thank you. It doesn't solve the problem, though. Anything after the wget line gets completely ignored. – JMH Sep 15 '13 at 17:52
1

The exit status 8 for wget means that for one of the file server returned error (e.g. 404):

Server issued an error response.

You may either want to fix the URLs, so they're point to the correct URLs, or ignore exit status of wget, e.g.

wget ... || true

Note: Above will work unless you've the pipefail option enabled.

Other way is to compare the exit status and ignore when it's returned 8, e.g.:

wget ... || { [ $? -ne 0 ] && [ $? -ne 8 ] && echo Success || exit 1; } 

See: Wget - Exit Status

kenorb
  • 155,785
  • 88
  • 678
  • 743