This program can be interesting for you if you want to write shell scripts on
Unix-like platforms - but in JavaScript instead of "sh" (bourne/bash/csh and
the like). All you need to know are the JavaScript basics and the usual suspects
among the console commands that you often use in the shell window (e.g. cd
,
mv
, cp
). To see the differences and similarities, risk a glance at these
shell script codes:
Dieses Programm kann für Dich interessant sein, wenn Du auf Unix-ähnlichen
Betriebssystemen Shell-Skripte schreiben willst - jedoch mit JavaScript statt
mit "sh" (Bourne shell/bash/csh usw.). Alles, was Du wissen musst, sind die
Grundkenntnisse von JavaScript und die üblichen Verdächtigen der Terminalbefehle
(cd
, mv
, cp
). Um den Unterschiede und Ähnlichkeiten zu erkennen, werfe
einen Blick auf diese Shell-Skripte:
Bash
#!/bin/sh
cd ~/Desktop
echo Hello world
pwd
ls *.txt
source otherscript.sh
c=1
while [ $c -le 5 ]; do
echo "Welcome $c times"
(( c++ ))
done
if [ -f $1 ]; then
echo "$1 is a file"
else
echo "$1 is no file" 1>&2
exit 1
fi
JavaScript
#!/usr/bin/sees
cd("~/Desktop");
alert("Hello world");
alert(pwd());
alert(ls("*.txt"));
include("otherscript.js");
var c=1;
while(c <= 5) {
alert("Welcome " + c + " times");
c++;
}
if(isfile(args[1])) {
alert(args[1] + " is a file");
} else {
throw args[1] + " is no file";
// exit(1) is not required
}
As you can see, the basic approach of SEES is implementing JavaScript code
similar to the normal shell scripting. The functions you often need are in the
global scope and not hidden in objects and sub-objects. JavaScript has also
advantages if you write mode complex code - however, for small and mainly sequential
scripts (like one if
, three cp
and one cd
), the bash is still the
tool you want to use.
Der deutlich erkennbare Ansatz von SEES ist, dass die JavaScript-Befehle den üblichen Shell-Kommandos möglichst ähnlich sind. Oft benötigte Funktionen sind im globalen Gültigkeitsbereich und nicht in irgendwelchen Objekten und Subobjekten versteckt. Weiterhin hat JavaScript Vorteile gegenüber Bash, wenn das Programm etwas komplexer wird. Allerdings sei auch gesagt, dass für hauptsächlich sequenzielle Abläufe die Bash immer noch das beste Tool ist.
Download and use
A binary is available for MacOS 10.6, you can download it here The source code is here. . There is explicitly no MacOS installer for it, as I don"t see a point to copy one single file to a binary directory if you possibly even don"t want this. This is a freeware program and comes without any warranties.
Download und Verwendung
Eine kompilierte Version für MacOS 10.6 habe ich hier zum Download bereitgestellt. Der Source Code ist hier. Es ist nur das Programm, kein Installer-Package: Ich sehe keinen Grund darin einen zu schreiben, nur um eine Datei in den Binary-Ordner zu verschieben (und dafür noch nach root-Rechten zu fragen), vor allem weil das vielleicht überhaupt nicht erwünscht ist. Das Programm ist Freeware und kommt daher ohne jegliche Gewährleistungen.
Run without installation
To run a JavaScript like a shell script with SEES from a folder you want, just do the following steps. These are actually almost the same steps when you create a bash script:
- Copy sees to this folder
- Create a JavaScript file in the folder (e.g. script.js)
- Make the JavaScript file executable using
chmod 711 script.js
- Put
#!/.sees
in the first line of the script - Thats it, you can implement your code, e.g.
echo("Hello world!");
- Run your script by typing
./script.js
in the shell window
Nutzung ohne Installation
Um ein JavaScript auf die gleiche Weise wie ein Shell-Skript aus einem beliebigen Ordner aus mit SEES auszuführen, gehe folgenderweise vor (d.h. ziemlich genau so, wie man bei bash-Skripten vorgeht):
- Kopiere SEES in diesen Ordner
- Erstelle ein neues JavaScript in dem Ordner (z.B. script.js)
- Mache die JavaScript-Datei ausführbar durch
chmod 711 script.js
- Tippe
#!/.sees
in die erste Zeile des Skripts - Und das war's schon, darunter kommt Dein Programm, z.B.
echo("Hello world!");
- Ausgeführt wird das Programm durch
./script.js
im Terminalfenster
Install SEES
Simply copy the sees
binary file to the /usr/bin
directory and give it the
right access permissions:
- Copy:
sudo cp sees /usr/bin
- Owner:
sudo chown root:wheel /usr/bin/sees
- Permissions:
sudo chmod 711 /usr/bin/sees
SEES installieren
Dazu muss einfach die Binärdatei sees
in den Ordner /usr/bin
kopiert und
ein paar Zugriffsrechte nachjustiert werden:
- Kopieren:
sudo cp sees /usr/bin
- Datei-Owner:
sudo chown root:wheel /usr/bin/sees
- Zugriffsrechte:
sudo chmod 711 /usr/bin/sees
Some Annotations
- The ".js" file extension is not required for the interpreter. If your script
shall look like a command, just name it with out an extension - like
dosomething
- You can make an additional private binary path where you put your scripts in:
- Create a new folder somewhere in your home directory, example:
mkdir ~/.bin
(this .bin folder will not be displayed in the Finder) - Open the file
~/.bash_profile
and add the lineexport PATH=$PATH:~/.bin
. If it is not yet in your home folder, create it - If your terminal program is open, quit the process (in the Dock, not only the windows) and reopen it to make the changes being reloaded
- Put your script files into your
~/.bin
folder - Now you can call your programs from everywhere you like
Noch ein paar Anmerkungen
- Die Dateierweiterung ".js" braucht der Interpreter nicht unbedingt. Wenn das
Skript wie ein Shellprogramm aussehen soll, lass die Erweiterung einfach weg -
Beispiel
dosomething
- Du kannst Dir einen eigenen Ordner erstellen, aus dem Du Deine Skripte überall ausführen kannst:
- Erstelle einen Ordner irgendwo im im Home-Verzeichnis, Beispiel:
mkdir ~/.bin
(dieser .bin wird wegen dem Punkt davor nicht im Finder angezeigt) - Öffne die Datei
~/.bash_profile
und füge die Zeileexport PATH=$PATH:~/.bin
ein. Wenn die Profildatei noch nicht im Home-Verzeichnis existiert, erstelle sie einfach - Wenn das Terminalprogramm noch läuft, schließe es (d.h. schieß den Prozess unten im Dock ab). Wenn das Terminal das nächste Mal geöffnet wird, sind die Einstellungen aktiv.
- Verschiebe Deine Skripte in diesen Ordner
~/.bin
- Fertig, jetzt können die Skripte von überall aus ausgeführt werden
Source code version
You can compile the sees-source for other Unix-like platforms using the GCC (I used GCC4.2.1). The zip contains a NetBeans project that should compile without changes (I have to admit that I still didn"t get it managed to create an autoconf project out of it, so if you have time and the proper toolbox installed on your machine - I would be glad :-) ).
Quelltext
Du kannst den SEES-Quelltext auch selbst für andere Unix-ähnliche Betriebssysteme mit dem GCC (ich habe den GCC4.2.1) kompilieren. Die Zip-Datei enthält ein Netbeans-Projekt, welches ohne Probleme kompilieren sollte. (Ich muss zugeben, dass ich bislang noch nicht die Zeit gefunden have, das Projekt in ein autoconf-Projekt zu konvertieren. Wenn Du die Zeit und die enteprechende Linux-Toolbox present hast, ich würde mich freuen :).
More about it ...
The shell interpreter is based on the Simple ECMAScript Engine (SEE), which is written by David Leonard and published under GPL compatible BSD license. SEE is a very slim and well functioning open-source JavaScript interpreter, which can be integrated in c/c++ projects. So SEES is "SEE for the Shell", uses the SEE library, sticks to the same license, and hence is an open-source project.
Weitere Informationen ...
Der Shell-Interpreter basiert auf der "Simple ECMAScript Engine" (SEE), welche von David Leonard geschrieben und unter der einer GPL-kompatiblen BSD-Lizenz veröffentlicht ist. SEE ist ein sehr schlanker und gut funktionierender JavaScript-Interpreter, der in c/c++ Projekte integriert werden kann. SEES ist also lediglich SEE für die Shell, benutzt die SEE-Bibliothek, ist unter der selben Lizenz veröffentlicht, und damit auch ein Open-Source-Projekt.
Synopsis
sees [-options] <script file> [<script arg1> [<script arg1> [...]]]
Libraries
You can write your own JavaScript libraries. The program will execute the following script files in the given order, if they exist:
Bibliotheken
Es ist möglich eigene JavaScript-Bibliotheken zu schreiben. Das Programm führt folgende Skripte (in der gleichen Reihenfolge wie in der Auflistung) beim Start aus, wenn sie existieren.
- /etc/sees/library.js
- /Library/Application Support/sees/library.js
- ~/.sees_library.js
- ~/Library/Application Support/sees/library.js
All functions and variables you define in your library are available in all your
scripts, as long you do not call sees with the switch "--no-library"
, e.g.
#!/usr/bin/sees --no-library
. Note that you can overload variables and functions.
If the function foo() {}
is implemented in /etc/sees/library.js
and in
~/.sees_library.js
, then the foo()
will do what ~/.sees_library.js
says.
Alle Funktionen und Variablen, die in der Bibliothek definiert werden, sind auch
in allen Skripten verfügbar, so lange Du sees nicht mit dem Kommandozeilenargument
"--no-library"
, z.B. #!/usr/bin/sees --no-library
ausführst. Beachte, dass
diese Variablen und Funktionen auch überschrieben werden können, D.h wenn
function foo() {}
in /etc/sees/library.js
und in ~/.sees_library.js
implementiert ist, dann wird foo()
tun was in ~/.sees_library.js
steht.
Short how-to
The most comments are posted in the blog category SEES, but here some basics in place.
Kurzes How-To
Die meisten Sachen sind in der Kategorie SEES veröffentlicht, jedoch seinen ein paar grundlegende Dinge hier beschrieben:
Reading text from a file
Here we use the function that we know from the shell: cat
:
Text aus einer Datei lesen
Wie von der Bash gewohnt wird hier die Funktion cat
verwendet:
alert("The text in the file is=" + cat("textfile.txt") );
Writing text in a file
As echo text > file
is used in bash, the alert
/print
/echo
functions have
two optional parameters:
Text in eine Datei schreiben
Da echo text > file
in der Bash verwendet wird haben die Funktionen alert
/ print
/ echo
optionale Parameter:
alert("My text", "~/textfile.txt"); // Replace the file if it exists
alert("My text", "~/textfile.txt", true); // Append text to the file if it exists
Command line arguments
Arguments are stored in the args[]
array. Like using the bash, the first parameter
args[0] is the program name/path. To test this script, call it with the command
line somehow like ./script argument1 "argument 2" and other arguments
.
Kommandozeilen-Argumente
Argumente werden im args[]
-Array gespeichert. Wie in der Bash ist der erste
Parameter args[0] der Programm-Name/-pfad. Um das folgende Skript zu testen füge
ein paar Kommandozeilenparameter hinzu, wie./script argument1 "argument 2" and
other arguments
:
alert("I am the script " + args[0] + ", and these are my arguments:");
for(var i=1; i < args.length; i++) {
alert(" args[" + i + "] = " + args[i]);
}
Input from pipes
You can input text from pipes, like cat file.txt | myscript.js
. If you do so,
then the content of the text file, which was passed to your script, will be
stored in the variable stdin
.
Eingabe von pipes
Dem Skript kann Text über den Standard-Eingabekanal (STDIN) übergeben werden,
z.B. cat file.txt | myscript.js
. Wenn das der Fall ist, so wird der Text,
welcher von cat an das Skript übergeben wird, in der Variablen stdin
gespeichert:
alert("I've got something from a pipe here:" + stdin);
Troubleshooting
- Interpreter throws a parse error: Make sure that your script is saved in UTF8, because you have probably some special characters in it like the German "ä", the French "é", the Spanish "ñ" or wherever you implement :-)
Troubleshooting
- Interpreter wirft einen Parse Error: Stelle sicher, dass dein Skript im UTF8-Format gespeichert ist, denn irgendwo verbirgt sich ein "ä", "ü" etc. Wenn das Skript nicht in Unicode gespeichert ist, dann hängt die richtige Darstellung von "ü" vom Betriebssystem ab, und daher arbeitet der Interpreter nur mit Unicode (wie fast alle JavaScript-Interpreter).
Reference of build-in objects, functions and variables
What you see below is a copy of the language extensions you get when you type
sees --help
. All the functions are explained with argument types, and the
mendatory brackets [ ]
for optional parameters.
Referenz der eingebauten Objekte, Funktionen und Variablen
Anbei eine Kopie der Spracherweiterung. Diese wird auch angezeigt, wenn Du
sees --help
eingibst. Alle Funktionen sind dort mit Typen angegeben, optionale
Parameter in obligatorischen eckigen Klammern:
Global variables
var String stdin
Contains the standard input passed to the script, e.g. by piping like
cat file.txt | script.js
var Array args
Contains the command line arguments passed to the script, e.g.
script.js -switch1 "Text argument 2" argument3
The first argument is always the script name (or what command you typed,
e.g. "./script.js" or "~/scripts/script.js"
Core extension functions and objects
function sh(String <command>)
Executes a shell command, writes stdout and stderr to the console and
returns the exit code.
function exec(String <command>, [Double <timeout in s>, String <stdin text>])
Executes a program and returns the exit code, the standard output and the
error output of the program as object. You can set a program timeout in
seconds and pass a text to the stdin pipe of the program.
Other than using function sh(), this function cannot evaluate shell
redirections like "echo Any test > file.txt" or "cat file.txt 2>1".
Instead, the results are saved in the object:
Object {
String stdout
String stderr
Integer exitcode
}
function print(String <text>, [String <file path>, Boolean <append=false>])
Prints the texts to the console standard output. If <file path> is
specified, the output is redirected to a file. Optionally the output
is appended at the end of the file
Returns nothing
function println(String <text>, [String <file path>, Boolean <append=false>])
Prints the texts to the console standard output and adds a new line
If <file path> is specified, the output is redirected to a file. Optionally
the output is appended at the end of the file
Returns nothing
function alert(String <text>, [String <file path>, Boolean <append=false>])
Prints the texts to the console standard output and adds a new line
(JavaScript known alias of println). If <file path> is specified, the
output is redirected to a file. Optionally the output is appended at the
end of the file.
Returns nothing
function include(String <path to JavaScript file>)
Executes a JavaScript. All variables and functions exists after the
include has finished (which allows you to write libraries. As the
import keyword is reserved and may be used later for explicit library
loading, we use include to load any file we want in the file system.)
Returns nothing
function exit(Integer <return code> )
Returns to the parent process with a spacified exit code
function env(String <variable>, [String <new value>])
Gets or sets the value of an environment variable
In both cases the actual value of the variable is returned
Object sees {
The object contains interpreter specific functions and data:
function compatibility()
Returns the interpreter JavaScript compatibility integer
function version()
Returns the program version as double
function gc()
Runs the SEE garbage collector
Returns nothing
function gcdump()
Dumps the SEE garbage collector
Returns nothing
function help()
Returns a string containing this help text
}
Shell-command (bash) derived functions
function echo(String <text>, [String <file path>, Boolean <append=false>])
Prints the texts to the console standard output and adds a new line
(Bash known alias of println). If <file path> is specified, the output is
redirected to a file. Optionally the output is appended at the end of the
file.
Returns nothing
function ls(String <dir/pattern>, [Boolean <show hidden>, Boolean <recursive>])
Lists directory contents (like shell command ls) If you search for hidden
files (e.g. ls(".*")), then <show hidden> is automatically switched on.
Returns an Array with file and directory names
function cd(String <directory>)
Changes the current working directory (like shell command cd)
Returns a String which contains the new directory
function cwd()
Returns a String which contains the current working directory
(like shell command cwd)
function pwd()
Returns a String which contains the current working directory
(like shell command cwd)
function mv(String <directory/file>, String <new location>)
Moves a file or directory like the mv shell command
Returns (nothing)
function cp(String <directory/file>, String <directory/file>)
Copys a file or directory like the cp shell command
Returns (nothing)
function ln(String <file/dir path>, String <link path>, [Boolean <hardlink>])
Creates a symbolic link or hard link to a file or directory.
Note that hard links to directories are normally forbidden.
Returns (nothing)
function rm(String <file>)
Deletes a file like the rm shell command
Returns (nothing)
function rmdir(String <directory>)
Deletes an empty directory like the rmdir shell command
Returns (nothing)
function unlink(String <file>)
Deletes a file or directory like the rm shell command
The function is an alias for rm()
Returns (nothing)
function mkdir(String <directory>)
Creates a directory with the permissoin 755
Returns (nothing)
function chmod(String <file/directory>, [Integer <permissions>])
Gets or sets the value of file permissions
The permissions can be set as string or integer, e.g. "777" or 711
In both cases the actual permission of the file is returned
function chown(String <file/directory>, [String <owner>])
Gets or sets the file owner
In both cases the actual owner of the file is returned
function chgrp(String <file/directory>, [String <group>])
Gets or sets the file group
In both cases the actual group of the file is returned
function touch(String <file/directory>, [<modification time>, <access time>])
Sets new modification and access time of a file. If <modification time>
of <access time> is not specified, the time is unchanged. If the file does
not exist, an empty regular file is created. The data types of the times
can be a UNIX timestamp, a Date object, or a string string (see date formats
section
function cat(String <file/directory>)
Returns the content of a file
function md5(String <file>)
Returns a String which contains the md5 checksum of a given path
function kill(Integer <PID>, [Boolean <immediately=false>])
Stops a running process by sending the signal SIGTERM. If the
argument <immediately> is true, the signal SIGKILL is sent, which is
not blockable. Use this parameter only if a process does not respond.
function basename(String <directory/file>)
Returns a String which contains the basename of a given path
function dirname(String <directory/file>)
Returns a String which contains the directory of a given path
Shell related functions which have not the same name as bash commands
function exist(String <path>, [boolean <dont't follow symlinks=false>])
Returns true if the <path> exists, else false
The function follows symlinks if second argument is not true.
function isfile(String <path>)
Returns true if <path> is a file, else false
The function always follows symlinks
function isdir(String <path>)
Returns true if <path> is a directory, else false
The function always follows symlinks
function islink(String <path>)
Returns true if <path> is a symbolic link, else false
The function never follows symlinks
function filesize(String <path>)
Returns the file size of <path> in bytes
function filectime(String <path>, [Boolean <dont' follow symlinks>])
Returns the file creation time of <path> as Date object
function filemtime(String <path>, [Boolean <dont' follow symlinks>])
Returns the file modification time of <path> as Date object
function fileatime(String <path>, [Boolean <dont' follow symlinks>])
Returns the file access time of <path> as Date object
function tmpfile()
Returns the path to a usable temporary file in the /tmp directory
function sha1(String <file>)
Returns a String which contains the sha1 checksum of a given path
The function is similar to 'shasum -a 1 <path>'
function sha256(String <file>)
Returns a String which contains the sha256 checksum of a given path
The function is similar to 'shasum -a 256 <path>'
function sha384(String <file>)
Returns a String which contains the sha384 checksum of a given path
The function is similar to 'shasum -a 384 <path>'
function sha512(String <file>)
Returns a String which contains the sha512 checksum of a given path
The function is similar to 'shasum -a 512 <path>'
Object extensions
String.prototype.trim()
Returns a String with spaces, tabs and newline characters chopped at the
beginning and end of the text.
String.prototype.ltrim()
Returns a String with spaces, tabs and newline characters chopped at the
beginning of the text.
String.prototype.rtrim()
Returns a String with spaces, tabs and newline characters chopped at the
end of the text.