Saturday, May 11, 2019

Running a Mongo Shell Script From Within A Larger Bash Script

If you have a Bash script that amongst other things needs to execute a set of multiple Mongo Shell commands together, there are a number of approaches that can be taken. This blog post contains nothing revelatory, but hopefully at least captures examples of these approaches in one single place for easy future reference. There are many situations where this is required, for example:
  • From within a Docker container image’s Entrypoint, running a Bash script which includes a section of Mongo Shell JavaScript code to configure a MongoDB replica-set, using rs.initiate() and associated commands.
  • From within a Continuous Integration process, running a Bash script which installs a MongoDB environment in a host Operating System (OS) and then populates the new MongoDB database with some sample data, using a set of Mongo Shell CRUD commands
  • From within a host system’s monitoring Bash script, which, in addition to gathering some host OS metrics, invokes a set of MongoDB’s server status and statistics commands to also capture database metrics.
The rest of this blog post shows some of the different approaches that can be taken to execute a block of Mongo Shell JavaScript code from within a larger Bash script. In these specific examples a trivial block of JavaScript code will insert 2 records into a ‘persons’ database collection, then query and print both the records belonging to the collection and then remove the 2 records from the collection.

It is worth noting that there is a difference in some of Mongo Shell’s behaviour when running a block of JavaScript code in the Mongo Shell’s Scripted mode rather than its Interactive mode, including the inability to run the Shell Helper commands (e.g. unable to utilise use db, show collections, etc.).


1. EXTERNAL SCRIPT FILE


This option requires executing a separate file which contains the block of JavaScript code. First create a new JavaScript file called test.js with the following content:

db = db.getSiblingDB('testdb');
db.persons.insertOne({'firstname': 'Sarah', 'lastname': 'Smith'});
db.persons.insertOne({'firstname': 'John', 'lastname': 'Jones'});
db.persons.find({}, {'_id': 0, 'firstname': 1}).forEach(printjson);
print(db.persons.remove({}));

Then create, make executable, and run a new Bash .sh script file with the following content (this will run the Mongo Shell in Scripted mode):

#!/bin/bash
echo "Doing some Bash script work first"
mongo --quiet ./test.js
echo "Doing some more Bash script work afterwards"


2. SINGLE-LINE EVAL SCRIPT


This option involves executing the Mongo Shell with its eval option, passing in a single line containing each of the JavaScript commands separated by a semicolon. Create, make executable, and run a new Bash .sh script file with the following content (this will run the Mongo Shell in Scripted mode):

#!/bin/bash
echo "Doing some Bash script work first"
mongo --quiet --eval "db = db.getSiblingDB('testdb'); db.persons.insertOne({'firstname': 'Sarah', 'lastname': 'Smith'}); db.persons.insertOne({'firstname': 'John', 'lastname': 'Jones'}); db.persons.find({}, {'_id': 0, 'firstname': 1}).forEach(printjson); print(db.persons.remove({}));"
echo "Doing some more Bash script work afterwards"

Note: Depending on your desktop resolution, your browser may show the Mongo Shell command wrapping onto multiple lines. However, it is actually just a single line, which can be proved by copying the line into a text editor which has its ‘text wrapping’ feature disabled.


3. MULTI-LINE EVAL SCRIPT


This option involves executing the Mongo Shell with its eval option, passing in a block of multiple lines of JavaScript code, where the start and end of the code block are delimited by single or double quotes. Create, make executable, and run a new Bash .sh script file with the following content (this will run the Mongo Shell in Scripted mode):

#!/bin/bash
echo "Doing some Bash script work first"
mongo --quiet --eval "
    db = db.getSiblingDB('testdb');
    db.persons.insertOne({'firstname': 'Sarah', 'lastname': 'Smith'});
    db.persons.insertOne({'firstname': 'John', 'lastname': 'Jones'});
    db.persons.find({}, {'_id': 0, 'firstname': 1}).forEach(printjson);
    print(db.persons.remove({}));
"
echo "Doing some more Bash script work afterwards"

Note: Care has to be taken to ensure that any quotes used within the JavaScript code block are single-quotes, if the Mongo Shell’s eval delimiters are double-quotes, or vice versa.


4. MULTI-LINE SCRIPT WITH HERE-DOC


This option involves redirecting the content of a block of JavaScript multi-line code into the standard input (‘stdin’) stream of the Mongo Shell program, using a Bash Here-Document. Create, make executable, and run a new Bash .sh script file with the following content (unlike the other approaches this will run the Mongo Shell in Interactive mode):

#!/bin/bash
echo "Doing some Bash script work first"
mongo --quiet <<EOF
    show dbs;
    db = db.getSiblingDB("testdb");
    db.persons.insertOne({'firstname': 'Sarah', 'lastname': 'Smith'});
    db.persons.insertOne({'firstname': 'John', 'lastname': 'Jones'});
    db.persons.find({}, {'_id': 0, 'firstname': 1}).forEach(printjson);
    print(db.persons.remove({}));
EOF
echo "Doing some more Bash script work afterwards"

In this case, because the Mongo Shell is run in Interactive mode, the output of the script will be more verbose. Also, by virtue of running in Interactive mode, the Shell Helpers commands can now be used within the JavaScript code. The block of code above contains the additional line show dbs; as the first line, to illustrate this. However, don’t take this example as a recommendation to use Shell Helpers in your scripts. Generally you should avoid using Shell Helpers in any of your Mongo Shell scripts, regardless of which approach you use.

Also, because the Mongo Shell eval option is not being used, the JavaScript code can contain a mix of both single and double quotes, as illustrated by the modified line of code db = db.getSiblingDB("testdb"); shown above, which utilises double-quotes.


Another Observation


It is worth noting that for all of these four methods, apart from the External Script File method, you can reference Bash environment variables inline within the Mongo Shell JavaScript code (as long as double-quotes deliminate the code for the eval methods, rather than single-quotes). For example, from a Bash terminal if you have set a variable with the name of the database to write to...

export DBNAME=testdb

... you can then use the value of this environment variable from within the inline Mongo Shell JavaScript...

db = db.getSiblingDB('${DBNAME}');

...to factor out the database name. At face value this may not seem particularly powerful until you realise that many build frameworks (e.g. Docker Compose, Ansible, etc.) allow you to declare environment variables within configuration settings before invoking Bash scripts, to factor out environment specific settings.

One bit of caution though, if you are using the MongoDB query operators, they include an ampersand in the syntax (e.g. '&gt', '&exists') which will need to be escaped in these scripts (e.g. '\&gt', '\&exists'). Otherwise Bash will treat each ampersand as a special control character which, in this case, will likely result in being replaced with some empty text.


Summary


The following table summarises the main differences between the four approaches to running a JavaScript block of code with the Mongo Shell, from within a larger Bash script:



Song for today: D. Feathers by Bettie Serveert

9 comments:

madin said...

Best cheap Soccer Jerseys Shirts Wholesale Shop for Custom Team Soccer Jerseys Online,cheap walter gael sandoval Jerseys FCB Jerseys,cheap Euro 2020 Kit Top.

madin said...

replica mont blanc uk is a brand with a long history. Founded in 1906, the replica mont blanc donation penscompany is named after one of the highest mountains in Europe, marking the brand's commitment to producing fine writing instruments. Using the brand that produces the best writing instruments, it helps to know how to find the Montblanc fountain pen that works best for you. From the best Montblanc fountain pens to ballpoint and ballpoint pens, you have a choice. Whether you are a collector or a keen writer, this article will take you to the top 10 Montblanc fountain pens on the market.

madin said...

Founded in 1905, Rolex watches have been in the uk replica rolex field of innovation for more than a century. The fake cosmograph daytona watches first certified precision chronograph, the first self-winding watch and the first effective waterproof case are milestones in Rolex design. Today, the Rolex brand is immediately recognized as a symbol of global reputation, luxury and innovation. Buying a Rolex watch means you are buying a watch history. Here we have a large catalog of used Rolex special watches for sale.

madin said...

Ha sido un hito en la industria desde que Longines estableció su marca en Saint-Imier en 1832.relojes réplica Hoy, la marca ofrece una variedad de relojes para hombres y mujeres. longines relojes réplicaLos relojes Longines se han utilizado a lo largo de la historia, desde la aventura hasta la expresión elegante. Además de ser conocido por su conexión con el mundo de las carreras y la equitación, Longines también es conocido mundialmente por su refinamiento elegante y atemporal. Tenemos una variedad de relojes Longines a la venta, todos nuevos, hermosos y garantizados para ser auténticos. Aún mejor, cuando compra Longines en línea, sabe que está obteniendo el mayor valor. Explore nuestra lista de selección para encontrar los mejores precios de relojes en Longines en Internet.

madin said...

Moncler S.p.A is an Italian apparel and lifestyle company, cheap moncler jackets most known for its down jackets and sportswear,replica man moncler jackets founded in 1952 by René Ramillon and André Vincent. Moncler took its name from the abbreviation of Monestier-de-Clermont, an Alpine town near Grenoble, France. Moncler is an abbreviation of Monastier de Clermont, the Alpine village where the brand was founded. Today its classic quilted down jackets with a sense of chic have made it the go-to outerwear label for active urbanites.

madin said...

Moncler have been developing their ski-inspired apparel replica moncler jackets since founded in 1952, replica man moncler jacketspopular for their luxe quilted down coats originally produced for extreme cold-weather conditions.Sportswear-inspired clothing combined with street-style provides practical and versatile daily-wear pieces including Moncler t-shirts and polos perfect under a lightweight jacket.

madin said...

high quality replica cartier watches is a noted jewelry brand with luxurious elegance and technical innovation.replica calibre de cartier diver blue watches It has massive selection of product lines ranging from jewellery, bridal, accessories, leather goods to timepieces. In our leading online shop, we are particularly specialized in selling Swiss replica Cartier watches. There is no denying the fact that Cartier watches are within the dream list of many women. However, they come with astronomical prices which are far beyond the reach of many people. In consideration of this problem, we website provide the final products of Swiss replica Cartier watches, which are much more authentic than that of our competitors, and at a fraction of the cost of originals. Furthermore, we always take attention to details, high-end materials, fine watchmaking and advanced design.

madin said...

replica longines watches is not the oldest among Swiss watchmakers but it has proven that it is deserving of its stature. replica mens longines master collection watches Established in 1832, its legacy still lives on as among the most trusted of watch brands, promising both quality in make and refinement. This is evident in the La Grande Classique, made for both men and women. The restrained elegance is not foreign to the brand, but La Grande Classique offers this with a svelte case.

madin said...

Alexander McQueen's performance is known for its emotional power, primitive energy,Replica ALEXANDER MCQUEEN and romantic but replica mens ALEXANDER MCQUEEN sandal determined contemporary nature. An essential element of McQueen's culture is the juxtaposition of contrasting elements: vulnerability and strength, tradition and modernity, fluidity and seriousness. In respecting the craftsmanship tradition, an open and even passionate view was realized. McQueen's collection combines an in-depth knowledge of British custom sewing, superb craftsmanship and impeccable craftsmanship made in Italy.