Translate

Translate to EnglishÜbersetzen Sie zum Deutsch/GermanΜεταφράστε στα ελληνικά/GreekПереведите к русскому/RussianOversetter til Norsk/NorwegianÖversätta till Svensk/Swedishहिन्दी अनुवाद करने के लिए/Hindi
Tradueix al català/CatalanTulkot uz latviešu/LatvianPreložiť do slovenčiny/SlovakVertaal aan het Nederlands/Dutchترجمة الى العربية/ArabicTraduzca al Español/SpanishTraduisez au Français/French
Traduca ad Italiano/ItalianTraduza ao Português/Portuguese日本語に翻訳しなさい /Japanese한국어에게 번역하십시오/Korean中文翻译/Chinese Simplified中文翻译/Chinese TraditionalПереклад на українську/Ukrainian
Image of Modern Operating Systems (3rd Edition)
Image of Linux Kernel Development (3rd Edition)
Image of Android Wireless Application Development
Image of RHCE Red Hat Certified Engineer Linux Study Guide (Exam RH302) (Certification Press)

KSH93 libshell

In a number of posts about a year ago I discussed how to develop custom builtins for Korn Shell 93 (ksh93) using libshell and published APIs. You can also use these same APIs to access ksh93 functionality from within a C application. This post provides three simple examples of how to do this.

The first example simply takes two numbers as arguments on the command line, multiplies the numbers and prints out the result on stderr.

#include <shell.h>
#include <nval.h>

int main(int argc, char *argv[])
{
    Namval_t *np;
    Sfdouble_t res;

    Shell_t *shp = sh_init(argc, argv, 0);
    sh_trap("((xresult=$0*$1))", 0);

    np = nv_open("xresult", shp->var_tree, 0);
    res = nv_getnum(np);
    sfprintf(sfstderr,"%Lg\n", res);
    nv_close(np);

    return(0);
}


Here is how to compile this example using static libraries. I built these examples in my home directory but the ksh93 build environment is at /work/ksh93, hence the use of -I and -L options. Note the large number of AST (Advanced Software Toolkit) and ksh93 libraries you have to specify in order to resolve all the symbols.

gcc -o example1 -I/work/ksh93/arch/linux.i386-64/include/ast example1.c  \
     -L/work/ksh93/arch/linux.i386-64/lib -lshell -lm -ldll -lcmd  -ldl -last


Here is the ouput for this example:

$ ./example1 3 4
12
$


The next example breaks the text string string into its component parts and prints them out to stdout. Note that “foo\\ bar” is one word, not two words.

#include <shell.h>
#include <stdio.h>
#include <nval.h>

int
main(int argc, char *argv[])
{
    char tmp[512];
    char string[] ="hello world 'my name is Finnbarr' foo\\ bar";

    sprintf(tmp, "set - %s && for i in \"$@\";\n do\n echo \"$i\"\ndone", string);

    Shell_t *shp = sh_init(argc, argv, 0);
    sh_trap(tmp, 0);

    return(0);
}


Here is the output:

./example2
hello
world
my name is Finnbarr
foo bar


The final example is similar to the previous example, except that it creates an array and then uses nv_getval() to access the contents of the created array and print the contents to stderr.

#include <shell.h>
#include <stdio.h>
#include <nval.h>

int
shell(int argc, char* argv[], char *str)
{
    Namval_t *np, *np_sub;
    char tmp[512];

    sprintf(tmp, "set - %s && for i in \"$@\";\n do\n aname+=(\"$i\")\ndone", str);

    Shell_t *shp = sh_init(argc, argv, 0);
    sh_trap(tmp, 0);

    np = nv_open("aname", shp->var_tree, 0);
    nv_putsub(np, NULL, ARRAY_SCAN);
    np_sub = np;

    do {
        // copy out the arguments to wherever here.
        fprintf(stderr, "%d: subscript='%s' value='%s'\n", np_sub, nv_getsub(np_sub), nv_getval(np_sub));
    } while (np_sub && nv_nextsub(np_sub)); 

    nv_close(np);

    return(0);
} 

int
main(int argc, char *argv[])
{
    char string[] ="hello world 'my name is simon' foo\\ bar";

    shell(argc, argv, string);
}


Here is the output:

$ ./example1
37212336: subscript='0' value='hello'
37212336: subscript='1' value='world'
37212336: subscript='2' value='my name is simon'
37212336: subscript='3' value='foo bar'
$


As you can see, running shell script snippets from within a C application is not difficult. For more information on these APIs read the ksh93 shell(3) and nval(3) man pages.
 

Comments are closed.