Linux Fu: Blending Bash and Python

Even though bash scripts are frequently maligned, they do have a definite simplicity and simplicity of advent that makes them onerous to withstand. However once in a while you in reality wish to perform a little heavy lifting in every other language. I’ll speak about Python, however in reality, you’ll be able to use many alternative languages with this method, even though it’s possible you’ll want somewhat adaptation, relying to your language of selection.

After all, you don’t need to do anything else particular to name every other program from a bash script. In the end, that’s what it’s basically used for: calling different techniques. On the other hand, it isn’t very at hand to have your script unfold out over more than one information. They are able to get out of sync and if you wish to ship it to anyone or every other gadget, you may have to bear in mind what to get. It’s nicer to have the entirety in one document.

The Paperwork are All Right here

The secret’s to make use of the ceaselessly forgotten right here report characteristic of bash. This works perfect when this system in query is an interpreter like Python.

 #!/bin/bash
echo Welcome to our shell script python <<__EOF_PYTHON_SCRIPT
print 'Hi there from Python!'
__EOF_PYTHON_SCRIPT echo "And we're again!"

Diversifications on a Theme

After all, any shell that helps right here paperwork can do that, now not simply bash. You’ll be able to use different interpreters, too. For instance:

#!/bin/bash
echo Welcome to our shell script perl <<__EOF_PERL_SCRIPT
print "Hi there from Perln"
__EOF_PERL_SCRIPT echo "And we're again!"

It could be complicated, however it’s essential also have some sections in Python and others in Perl or every other language. Check out to not get over excited.

Simply in Case

There’s the uncommon case the place an interpreter doesn’t take the interpreted document from the usual enter. Awk is a infamous perpetrator. Whilst you’ll be able to embed all of the script within the command line, that may be awkward and results in quoting hassles. However it kind of feels foolish to put in writing out a short lived document simply to ship to awk. Thankfully, you don’t need to.

There are a minimum of two commonplace tactics to maintain this downside. The primary is to make use of the bash procedure substitution. This principally creates a short lived document from a subshell’s same old output:

#!/bin/bash
# Hybrid bash/awk Phrase rely program -- utterly needless, after all... echo Counting phrases for "[email protected]"
awk -f <( cat - <<EOF_AWK BEGIN { wcount=0; lcount=0; } { lcount++; wcount+=NF; } END { print "Traces=" lcount; print "Phrases=" wcount; } EOF_AWK
) "[email protected]" echo Hope that used to be sufficient
go out 0

But Every other Method

There may be differently to prepare your procedure substitutions, so they’re all amassed in combination on the finish of the script surrounded via a marker comparable to “AWK_START” and “AWK_END” or some other pair of strings you prefer. The speculation is to place every pseudo document in its personal segment on the finish of the script. You’ll be able to then use any collection of ways like sed or awk to strip the ones strains out and procedure change them like prior to.

There are two minor issues. First, the script must go out prior to the pretend information get started. That’s simple. You simply need to be sure you code an go out on the finish of the script, which you most likely must do anyway. The opposite downside is in search of the marker textual content. In case you seek the document for, say, AWK_START, you want to verify the hunt trend itself isn’t discovered. You’ll be able to repair this via the usage of some arbitrary brackets within the seek string or breaking apart the hunt string. Believe this:

#!/bin/bash
# Hybrid bash/awk Phrase rely program -- utterly needless, after all... echo Counting phrases for "[email protected]"
# use brackets
#awk -f <( sed -e '/[A]WK_START/,/[A]WK_END/!d' $0 ) "[email protected]"
# or
AWK_PREFIX=AWK
awk -f <( sed -e "/${AWK_PREFIX}_START/,/${AWK_PREFIX}_END/!d" $0 ) "[email protected]" echo Hope that used to be sufficient
go out 0 # the entirety underneath right here would be the supporting "information", on this case, simply one for awk # AWK_START BEGIN { wcount=0; lcount=0;
} { lcount++; wcount+=NF;
} END { print "Traces=" lcount; print "Phrases=" wcount;
} #AWK_END

There’s no reason why it’s essential now not have more than one pretend information on the finish, every with a distinct pair of markers. Do word, even though, that the markers are despatched to this system which is why they seem as feedback. If those have been going to a program that didn’t use # as a remark marker, you’d wish to trade the marker strains slightly, write a extra complicated sed expression, or upload some instructions to take off the primary and closing strains prior to sending it.

That’s a Wrap

You must argue that you’ll be able to do all you want to do in one language and that’s virtually no doubt true. However having some tips to embed more than one information inside of a document could make growing and distributing scripts more uncomplicated. That is relatively very similar to how we made self-installing archive information in a prior installment of Linux Fu. In case you’d fairly script in C or C++, you’ll be able to do this too.