Can I write scripts in C ++?


Recently I had to plunge again / again into the wonderful world of Linux script programming. In principle, the matter is not very tricky, but since I come across such tasks not often, I study it again every time. I know for sure that tomorrow I will forget a lot and in a month I will google again how to do this or that. The problem still turns out that often you don’t write the script again, but you modify the existing one already written by someone. And it may not be bash, but sh or something else ... There are differences in the syntax, what works in sh should work in bash, but not always the other way around. And if there is dash or ash? I don’t know ... There are still differences in these scripting languages, and they are confusing. And of course, for me personally, the cherry on the cake when the script calls some sed or awk and there are such parameters on the command line that you look at them and wonder.It is clear that this all depends on the qualifications of the programmer, but not everything fits in my head. And now my patience is gone and I thought that from now on I want to try writing scripts in c ++ ...

I understand that for true system administrator, my thought may seem seditious. But why not?

So the idea is very simple. I want to write c ++ scripts in the same way as regular scripts are written, that is, the first line of the script should contain shebang and an indication of the path to the "interpreter":

#!/bin/c++

The subsequent lines of the script will be just a regular c ++ program.

I have to prepare the "interpreter" of the c ++ script. You can write it on anything, at least on bash (this is the last time, although not exactly). Of course, it will not be an interpreter, but a compiler.

That's what I did:

#!/bin/bash

msg_file=/dev/null
#msg_file=/dev/stdout

tmp_path=$HOME"/.cache/c++/"
mkdir -p $tmp_path
tmp_file=$1".c++"
exe_file=$1".bin"
if test $1 -nt  $tmp_path$exe_file; then
    echo "Need to recompile.." > $msg_file
    tail -n +2 $1 > $tmp_path$tmp_file
    eval "g++ -o $tmp_path$exe_file $tmp_path$tmp_file > /dev/null 2>&1"
    if [ $? -eq 0 ]
    then
	echo "Compiled ok" > $msg_file
    else
	echo "Compile error" > $msg_file
	exit 255
    fi
fi
eval "$tmp_path$exe_file $@1"

This script does everything you need. As the temporary folder, I chose the ~ / .cache / c ++ folder. The original script will be copied to this folder, but without the first line with shebang. This is done by the tail command. The name of the new file will be like the original script, but with the extension c ++. The binary with the extension .bin will be collected in the same folder. But first, of course, an “if test” check is done at the time the binary is created. Compilation occurs only if the existing binary is outdated in time with respect to the original “script”. The binary is launched with the eval command and all initial parameters are passed to it.

This c ++ file needs to be copied to the / bin folder and made it executable (chmod a + x).

I’ll try to write my first “c ++ script”:

#!/bin/c++

#include <stdio.h>
#include <iostream>

using namespace std;

int main( int argc, char *argv[] )
{
    cout << "hello world!\n";
    for( int i=0; i<argc; i++)
    {
	cout << "Param" << i <<  " is " << argv[i] << "\n";
    }
    return 60+argc;
}

This program simply prints a list of input parameters and returns their number + 60. I
run my "script":



It works !!!

If you make an error in c ++ code, the program will not start, since it will not compile, but echo $? will return 255. But that was what was intended.

Using c ++ provides tremendous opportunities. First, the familiar syntax. Secondly, standard classes like std :: vector, std :: map or std :: string and others are irreplaceable things. The same line - whatever you want to do with it, look in the line, break it into substrings, disconnect and conquer, get arrays. And I do not need either sed or awk. Thirdly, the debugger - God! what a blessing! I have a gdb debugger for the script! Further, you can use std :: filesystem (if the compiler allows). You can go on ...

Unfortunately, it often happens with me that I will do it first, and then I will think: “what if someone has already done this?” And in fact, I am not the first to come up with the idea to do the same. Here is an example: https://github.com/dimgel/cpp-linux-scripts the idea is the same, the implementation is different. Then it turned out that there are other implementations .

In general, I experienced a slight disappointment in my own non-exclusivity. However, I looked for Habr - I did not find a similar one. Maybe someone seems at least curious?

All Articles