
systemfunc
Executes a shell command and returns the output.
Prototype
function systemfunc ( command [1] : string ) return_val [1] : string
Arguments
commandA singly dimensioned string containing a shell command to execute.
Return value
Returns a singly dimensioned string array containing the output from the executed shell command.
Description
This function passes the string command to the shell environment for execution. When the command completes, the output from the shell command is returned to NCL as a string, and control is returned to NCL.
The default shell used to execute command is /bin/sh (Bourne Shell). A different shell may be specified in command; to use a different shell, such as the C-Shell, commands are enclosed in single quotes (') to prevent the Bourne Shell from interpreting the commands. If the C-Shell command itself contains single quotes, they must be escaped with a '\'. See Example 5 below.
Using the systemfunc command, an NCL script can perform tasks often accomplished via a Linux/Unix shell script.
See Also
Examples
Example 1
Retrieve the current time and date and return as a string:
TimeDate = systemfunc("date")This returns a string of the form: TimeDate = "Tue Apr 11 14:30:44 MDT 2000".
Example 2
Use several Linux/Unix tools to create a UTC (Coordinated Universal Time) time. The Linux/Unix command date -u returns the time as GMT (Greenwich Mean Time).
; "date -u" returns a string of the form: "Tue Feb 18 16:48:31 GMT 2003" UTC = systemfunc("date -u '+%H%M UTC %e %b %Y'| awk '{print toupper($0)}'") print(UTC) ; 1648 UTC 18 FEB 2003Example 3
Retrieve a list of files from the current directory using wild cards:
myFiles = systemfunc("ls *.nc") ; return all netCDF filesmyFiles will be a singly dimensioned array of strings.
Example 4
Retrieve a list of files from another directory:
diri = "/ptmp/user/data/AnnualData/" fils = systemfunc("ls " + diri + "annual*") print(fils) ; full path to files
Variable: fils Type: string Total Size: 40 bytes 5 values Number of Dimensions: 1 Dimensions and sizes: [5] Coordinates: (0) /ptmp/user/data/AnnualData/annual.1974.nc (1) /ptmp/user/data/AnnualData/annual.1975.nc (2) /ptmp/user/data/AnnualData/annual.1976.nc (3) /ptmp/user/data/AnnualData/annual.1977.nc (4) /ptmp/user/data/AnnualData/annual.1978.ncExample 5
Retrieve a list of files from another directory, but do not include the directory; use the C-Shell (csh) syntax. To prevent the Bourne Shell from attempting to interpret C-Shell syntax, commands are enclosed by single quotes ('). If the C-Shell command itself contains single quotes, they must be escaped with a '\'.
First, use the Linux/Unix command cd to change directory location to the desired directory, and then list the appropriate files:
diri = "/ptmp/user/data/AnnualData/" fils = systemfunc ("csh -c 'cd " + diri + " ; ls annual*'") print(fils) ; relative path to files
Variable: fils Type: string Total Size: 40 bytes 5 values Number of Dimensions: 1 Dimensions and sizes: [5] (0) annual.1974.nc (1) annual.1975.nc (2) annual.1976.nc (3) annual.1977.nc (4) annual.1978.ncExample 6
The following is based on an ncl-talk query:
I have a directory "main" which has 20 subdirectories "a1", "a2", "a3", "a4",....... "a20" Each of these 20 subdirectories have 3 netcdf files each. How do I get the list of netcdf file names (20*3=60 file names) from "main" directory using systemfunc?
Response: Let's say the files are in "/home/user/main". You could do something like this: cmd = "find /home/user/main/a* -type f -print" fili = systemfunc(cmd) You can also use variables: dir = "/home/user/main" cmd = "find " + dir + "/a* -type f -print" fili = systemfunc(cmd)Example 7
Some simple uses of the Unix/Linux awk tool as implemented via systemfunc. NOTE: awk returns values of type string. The ls -l returns nine items.
- Retrieve a list of file names with a specific size (here, 4616028).
- Retrieve a list of all file sizes in the current directory.
- Retrieve the file size of a specific file.
Note that the first file name/size is empty. List from the 1st file The file size is item (argument) 5 while the file name is argument 9.
fname = systemfunc("ls -l | awk '{if ($5 = 4616028) print $9}'" ) ; type string print(fname) ; Note that the initial file name is not appropriate print(fname(1:)) ; start from 1 .... 0 is bogus fsizes = systemfunc("ls -l | awk '{print $5}' ") fsize = toint(fsizes(1:)) diri = "/my/data/" fili = "3B42.020301.3.6.nc" fszs = systemfunc("ls -l "+diri+fili+" | awk '{print $5}' ") fsz = toint(fszs)Example 8
The following is based on an ncl-talk query:
Is there is a way for 'live' interaction between an NCL script and user?
Yes.
print("=======> Enter integer a:") ;a = stringtointeger(systemfunc("read ifland; echo $ifland")) ; up thru 5.1.1 a = toint(systemfunc("read ifland; echo $ifland")) ; 5.2.0 print(a)Example 9
The following is based upon am ncl-talk response by Karin Meier-Fleischer (DKRZ).
You can use NCLs 'systemfunc' function with the shell function 'test' to check if a directory exists.
test -d directory; echo $? returns 0 if directory exist or 1 if not E.g. dirnames = (/"/tmp", "dirB", "$HOME"/) ndirs = dimsizes(dirnames) do i=0,ndirs-1 ret = systemfunc("test -d "+dirnames(i)+"; echo $?") if(ret .eq. 0) then print("--> "+dirnames(i)+": exists") ;-- do what you want to do else if(ret .eq.1) then print("--> "+dirnames(i)+": doesn't exist") ;-- just continue continue end if end if end doIf the directory does not exist and you wish to create the directory 'on-the-fly' rather than just 'continue', the following can be done
.... if(ret .eq. 0) then print("--> "+dirnames(i)+": exists") ;-- do what you want to do else if(ret .eq.1) then print("--> "+dirnames(i)+": doesn't exist: create") ;-- create the desired directory system("mkdir " + dirnames(i)) end if end if
Example 10:
Consider netCDF files in a suite of directories 1985, 1986,....1990, 1999, 2000, 2009, 2010, 2015. Each has one or more netCDF files. They may be accessed via:
fils = systemfunc("ls [1-2][8-9-0-1]*/*nc") print(fils) f = addfiles (fils, "r") x = f[:]->X printVarSummary(x)Edited output:
Variable: fils Type: string [snip] Dimensions and sizes: [31] [snip] 1985/foo.1985_time.nc .... 1995/foo.1995_time.nc .... 2008/foo.2008_time.nc 2009/foo.2009_time.nc 2010/foo.2010_time.nc .... 2015/foo.2015_time.ncSee Examples 4 and 5 at system.