Program name: Difference between revisions
(Added LLVM) |
(→{{header|C}}: Show __progname and p_comm for BSD.) |
||
Line 5: | Line 5: | ||
=={{header|C}}== |
=={{header|C}}== |
||
It might not be very useful for a C program to access source filenames, because C code must be compiled into an executable, and anything could have happened to the source file after the compilation. However, C can access the executable's |
It might not be very useful for a C program to access source filenames, because C code must be compiled into an executable, and anything could have happened to the source file after the compilation. However, C can access the executable's name in <code>argv[0]</code>. |
||
* <code>argv[0]</code> might be the name of an executable in the PATH, or it might be an absolute or relative path to the executable. At least with [[Unix]], the parent process can set <code>argv[0]</code> to any string, so <code>argv[0]</code> might not be the real name. It is best to pretend that <code>argv[0]</code> has the correct value, but mind that <code>argv[0]</code> might not be an actual file. |
|||
<lang c>#include <stdio.h> |
<lang c>#include <stdio.h> |
||
Line 24: | Line 26: | ||
return 0; |
return 0; |
||
}</lang> |
}</lang> |
||
=== BSD === |
|||
[[BSD]] provides two more ways to get the program's name. |
|||
# <code>__progname</code> is the filename from <code>argv[0]</code> (so if <code>argv[0]</code> is a path, then <code>__progname</code> is only the filename). No header file declares <code>__progname</code>, so programs must declare <code>extern char __progname;</code> to use it. |
|||
# <code>p_comm</code> always gives the real filename of the executable, even if <code>argv[0]</code> has a different name. <code>p_comm</code> is a field in the process information. Tools like ps(1) and top(1) use <code>p_comm</code>, but almost no other program uses <code>p_comm</code>, because the API is so difficult. |
|||
Build the next program with <code>make myname LDLIBS=-lkvm</code> |
|||
{{libheader|BSD libc}} |
|||
{{works with|OpenBSD|4.9}} |
|||
<lang c>/* myname.c */ |
|||
#include <sys/param.h> |
|||
#include <sys/sysctl.h> /* struct kinfo_proc2 */ |
|||
#include <err.h> |
|||
#include <fcntl.h> /* O_RDONLY */ |
|||
#include <kvm.h> |
|||
#include <limits.h> /* _POSIX2_LINE_MAX */ |
|||
#include <stdio.h> |
|||
int |
|||
main(int argc, char **argv) { |
|||
extern char *__progname; /* from crt0.o */ |
|||
struct kinfo_proc2 *procs; |
|||
kvm_t *kd; |
|||
int cnt; |
|||
char errbuf[_POSIX2_LINE_MAX]; |
|||
printf("argv[0]: %s\n", argv[0]); |
|||
printf("__progname: %s\n", __progname); |
|||
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); |
|||
if (kd == NULL) |
|||
errx(1, "%s", errbuf); |
|||
procs = kvm_getproc2(kd, KERN_PROC_PID, getpid(), |
|||
sizeof procs[0], &cnt); |
|||
if (procs == NULL) |
|||
errx(1, "%s", kvm_geterr(kd)); |
|||
printf("p_comm: %s\n", procs[0].p_comm); |
|||
kvm_close(kd); |
|||
return 0; |
|||
}</lang> |
|||
The program can have three different names! |
|||
<pre>$ perl -e 'exec {"./myname"} "/nobin/fakename"' |
|||
argv[0]: /nobin/fakename |
|||
__progname: fakename |
|||
p_comm: myname</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
Revision as of 03:36, 6 August 2011
It is useful to programmatically access a program's name, e.g. for determining whether the user ran "python hello.py", or "python hellocaller.py", a program importing the code from "hello.py".
Examples from GitHub.
C
It might not be very useful for a C program to access source filenames, because C code must be compiled into an executable, and anything could have happened to the source file after the compilation. However, C can access the executable's name in argv[0]
.
argv[0]
might be the name of an executable in the PATH, or it might be an absolute or relative path to the executable. At least with Unix, the parent process can setargv[0]
to any string, soargv[0]
might not be the real name. It is best to pretend thatargv[0]
has the correct value, but mind thatargv[0]
might not be an actual file.
<lang c>#include <stdio.h>
int main(int argc, char **argv) { printf("Executable: %s\n", argv[0]);
return 0; }</lang>
To get the source information about some part of code, use compiler defined macros. Most compilers support them or some variation of. <lang c>#include <stdio.h>
int main() { printf("This code was in file %s in function %s, at line %d\n", __FILE__, __FUNCTION__, __LINE__); return 0; }</lang>
BSD
BSD provides two more ways to get the program's name.
__progname
is the filename fromargv[0]
(so ifargv[0]
is a path, then__progname
is only the filename). No header file declares__progname
, so programs must declareextern char __progname;
to use it.p_comm
always gives the real filename of the executable, even ifargv[0]
has a different name.p_comm
is a field in the process information. Tools like ps(1) and top(1) usep_comm
, but almost no other program usesp_comm
, because the API is so difficult.
Build the next program with make myname LDLIBS=-lkvm
<lang c>/* myname.c */
- include <sys/param.h>
- include <sys/sysctl.h> /* struct kinfo_proc2 */
- include <err.h>
- include <fcntl.h> /* O_RDONLY */
- include <kvm.h>
- include <limits.h> /* _POSIX2_LINE_MAX */
- include <stdio.h>
int main(int argc, char **argv) { extern char *__progname; /* from crt0.o */
struct kinfo_proc2 *procs; kvm_t *kd; int cnt; char errbuf[_POSIX2_LINE_MAX];
printf("argv[0]: %s\n", argv[0]); printf("__progname: %s\n", __progname);
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); if (kd == NULL) errx(1, "%s", errbuf); procs = kvm_getproc2(kd, KERN_PROC_PID, getpid(), sizeof procs[0], &cnt); if (procs == NULL) errx(1, "%s", kvm_geterr(kd));
printf("p_comm: %s\n", procs[0].p_comm);
kvm_close(kd); return 0; }</lang>
The program can have three different names!
$ perl -e 'exec {"./myname"} "/nobin/fakename"' argv[0]: /nobin/fakename __progname: fakename p_comm: myname
C++
C++ has difficulty accessing source code filenames, because C code must be compiled into an executable. However, C++ can access the executable's filename.
<lang cpp>#include <iostream>
using namespace std;
int main(int argc, char **argv) { char *program = argv[0]; cout << "Program: " << program << endl;
return 0; }</lang>
Chicken Scheme
Getting the program name is tricky. When interpreted, the script name will be printed. When compiled, the executable name will be printed.
<lang scheme>#!/bin/bash
- |
exec csi -ss $0 ${1+"$@"} exit |#
(use posix) (require-extension srfi-1) ; lists (require-extension srfi-13) ; strings
(define (main args) (let ((prog (cdr (program)))) (display (format "Program: ~a\n" prog)) (exit)))
(define (program) (if (string=? (car (argv)) "csi") (let ((s-index (list-index (lambda (x) (string-contains x "-s")) (argv)))) (if (number? s-index) (cons 'interpreted (list-ref (argv) (+ 1 s-index))) (cons 'unknown ""))) (cons 'compiled (car (argv)))))
(if (equal? (car (program)) 'compiled) (main (cdr (argv))))</lang>
Clojure
If the shebang is used to run the script directly, this prints the script name. Otherwise, it prints nil.
<lang clojure>":";exec clj -m `basename $0 .clj` $0 ${1+"$@"} ":";exit
(ns scriptname (:gen-class))
(defn -main [& args] (def program (nth args 0)) (println "Program:" program))</lang>
Common Lisp
Shebangs require a special tweak to ~/.clisprc.lisp.
<lang lisp>;;; Play nice with shebangs (set-dispatch-macro-character #\# #\!
(lambda (stream character n) (declare (ignore character n)) (read-line stream nil nil t) nil))</lang>
<lang lisp>#!/bin/bash
- |
exec clisp -q -q $0 $0 ${1+"$@"} exit |#
- Usage
- ./scriptname.lisp
(defun main (args)
(let ((program (car args))) (format t "Program: ~a~%" program) (quit)))
- With help from Francois-Rene Rideau
- http://tinyurl.com/cli-args
(let ((args
#+clisp ext:*args* #+sbcl sb-ext:*posix-argv* #+clozure (ccl::command-line-arguments) #+gcl si:*command-args* #+ecl (loop for i from 0 below (si:argc) collect (si:argv i)) #+cmu extensions:*command-line-strings* #+allegro (sys:command-line-arguments) #+lispworks sys:*line-arguments-list* ))
(if (member (pathname-name *load-truename*) args :test #'(lambda (x y) (search x y :test #'equalp))) (main args)))</lang>
D
Will print name of executable. <lang d>import std.stdio;
void main(string[] args) {
writeln(args[0]);
}</lang>
Emacs Lisp
<lang lisp>:;exec emacs -batch -l $0 -f main $*
- Shebang from John Swaby
- http://www.emacswiki.org/emacs/EmacsScripts
(defun main ()
(let ((program (nth 2 command-line-args))) (message "Program: %s" program)))</lang>
Erlang
Erlang's macros hold information about the running module.
<lang erlang>-module(scriptname).
main(_) -> Program = ?FILE, io:format("Program: ~s~n", [Program]).</lang>
Haskell
Haskell has an impure function for this.
<lang haskell>#!/usr/bin/env runhaskell
module ScriptName where
import System (getProgName)
main :: IO () main = do program <- getProgName putStrLn $ "Program: " ++ program</lang>
Java
Java mainly has notions of classes.
<lang java>public class ScriptName { public static void main(String[] args) { String program = new ScriptName().getClass().getName(); System.out.println("Program: " + program); } }</lang>
LLVM
Like C, LLVM can use argv to access the executable's filename.
<lang sh>$ make llvm-as scriptname.ll llc scriptname.bc gcc -o scriptname scriptname.s ./scriptname Program: ./scriptname</lang>
Makefile
<lang make>all: scriptname.ll llvm-as scriptname.ll llc scriptname.bc gcc -o scriptname scriptname.s ./scriptname
clean: -rm scriptname -rm scriptname.s -rm scriptname.bc</lang>
<lang llvm>@msg_main = internal constant [13 x i8] c"Program: %s\0A\00"
declare i32 @printf(i8* noalias nocapture, ...)
define i32 @main(i32 %argc, i8** %argv) { %program = load i8** %argv call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @msg_main, i32 0, i32 0), i8* %program)
ret i32 0 }</lang>
Lua
Lua's arg is like C's argv.
<lang lua>#!/usr/bin/env lua
function main(arg) local program = arg[0] print("Program: " .. program) end
if type(package.loaded[(...)]) ~= "userdata" then main(arg) else module(..., package.seeall) end</lang>
newLISP
newLISP has a function, (main-args int) for this.
<lang lisp>#!/usr/bin/env newlisp
(let ((program (main-args 1)))
(println (format "Program: %s" program)) (exit))</lang>
Node.js
Node.js has a global variable for this.
<lang javascript>#!/usr/bin/env node /*jslint nodejs:true */
function main() { var program = __filename; console.log("Program: " + program); }
if (!module.parent) { main(); }</lang>
Perl
<lang perl>#!/usr/bin/env perl
use strict; use warnings;
sub main { my $program = $0; print "Program: $program\n"; }
unless(caller) { main; }</lang>
Perl 6
In Perl 6, the name of the program being executed is in the special global variable $*PROGRAM_NAME. <lang perl6>say $*PROGRAM_NAME;</lang>
PHP
PHP has a global dictionary for this.
<lang php><?php $program = $_SERVER["SCRIPT_NAME"]; echo "Program: $program\n"; ?></lang>
Python
<lang python>#!/usr/bin/env python
import inspect
def main(): program = inspect.getfile(inspect.currentframe()) print "Program: %s" % program
if __name__=="__main__": main()</lang>
R
R's syntax is complicated, but doable.
<lang R>#!/usr/bin/env Rscript
getProgram <- function(args) { sub("--file=", "", args[grep("--file=", args)]) }
args <- commandArgs(trailingOnly = FALSE) program <- getProgram(args)
cat("Program: ", program, "\n")
q("no")</lang>
Ruby
<lang ruby>#!/usr/bin/env ruby
def main program = __FILE__ puts "Program: #{program}" end
if __FILE__==$0 main end</lang>
Tcl
<lang tcl>#!/usr/bin/env tclsh
proc main {args} {
set program $::argv0 puts "Program: $program"
}
if {$::argv0 eq [info script]} {
main {*}$::argv
}</lang>
UNIX Shell
In Bash: <lang sh>#!/usr/bin/env sh
export program=$BASH_SOURCE echo "Program: $program"</lang>