how to execute command in console of program (i.e. various databases) through shell/bash script

I would like to have script that starts console (i.e. of database postgres or mongo) and to execute some commands that are known to work,

one of solutions is

file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234)

cat file.sh | mongo <EXPECTED_COLLECTION>

it feels like monkey patching (sure it can be closed in another script) so are there more "professional" ways to do it?


Solution 1:

cat file.sh | mongo … is UUOC, <file.sh mongo … is better.

Side note: why .sh? It doesn't matter to mongo or whatever, but people will expect file.sh to be a shell script. From now on I'm using file1 instead.

man 1 mongo gives an example: mongo script1.js script2.js script3.js, so I expect mongo … file1 to work as well.

#!/path/to/mongo or #!/usr/bin/env mongo can be used as a shebang. Use the shebang in file1, make the file executable (chmod +x file1) and run it directly (e.g. by typing ./file1 in its directory). Place file1 in a directory specified in your PATH and you will be able to run it by simply calling file1.

Note a shebang specifies an interpreter and at most one additional argument. Technically you can add one argument (like your <EXPECTED_COLLECTION>) after #!/path/to/mongo (but not after #!/usr/bin/env mongo where mongo is the argument), but I would rather do everything in JavaScript below the shebang.

you can specify the mongodb connection parameters inside of the javascript file using the Mongo() constructor.

(source)

psql is somewhat different. A basic way to interpret a script is psql -f file2 (psql <file2 should also work, but see what man 1 psql says about it where it describes -f).

A shebang like #!/path/to/psql -f would work, if psql ignored lines starting with # (like e.g. sh does) or if it at least recognized #!… in the first line as a shebang and skipped the line. It doesn't. There are few tricks to circumvent this; see Shebang for psql.


One of the answers from the last link uses a here document in a shell script. This approach is quite powerful. An example of a Python script inside a Bash script is here: How to include python script inside a bash script? Similarly you can pass an embedded script to mongo … (or to psql -f -):

#!/bin/sh

mongo … << 'EOF'
db.EXPECTED_COLLECTION.remove("_id":1234)
EOF

If you call this script file.sh then the .sh part will not be misleading. It is a shell script.

Note << EOF instead of << 'EOF' will allow you to pass expanded variables from the shell to mongo.