开发者

How can Linux program know how it was started: from command line? or by cron or something else?

Subject says it all: the program, running under Linux, needs to know how it was started. How to do that?开发者_运维百科

Thanks!

-- pete


When run at the command line, usually at least one of the standard file descriptors is a terminal, and even if not, there usually exists a controlling terminal. This is not usually true when run from cron.

if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO))
     puts("One of my standard file descriptors is a terminal");

int fd = open("/dev/tty", O_RDWR);
if (fd != -1) {
    puts("I have a controlling terminal");
    close(fd);
}

There are other differences, like environment and so on, but none of these are reliable. (Even those getppid solutions won't necessarily work — cron probably starts your job inside a sh.)


I think you might be looking for a solution to a problem that shouldn't exist. A program shouldn't care who launched it. You can use environment variables and command line switches to change the expected behavior of your application.

If you must know how an application is launched you may be able to hack something together by using the ps command but I wouldn't recommend it.


The first argument of a program is usually the command used to run it.

Example in bash:

$ cat /tmp/argv0.sh
echo $0
$ bash /tmp/argv0.sh
/tmp/argv0.sh
$ cd /tmp/ && bash ./argv0.sh
./argv0.sh


You can get the parent process identifier to see what started the program. If the program was invoked from cron, you could walk the process table via PID to the shell forked by cron and cron itself:

getppid(3) - Linux man page

Name

getppid - get the parent process ID

Synopsis

#include <unistd.h>

pid_t getppid(void);

Description

The getppid() function shall return the parent process ID of the calling process.

Return Value

The getppid() function shall always be successful and no return value is reserved to indicate an error.


Hey, in Linux ,as in every Unix-like system, each process is a (sub)-child of the init-process. To view this call tree just use the command ps.

e.g.: ps -ejH gives you a nice call tree

for further output options view the man page of ps.


If you literally want to know if you're running under "cron" you could get your parent process id, and then look in /proc to find the parent process name. For example:

#!/bin/sh 
PARENT_PID=`ps -p $$ -o ppid=` 
PARENT_CMD=`cat /proc/$PARENT_PID/cmdline` 
echo "parent = $PARENT_PID $PARENT_CMD"


Here is what I use to determine the parent of a process among cron, at, and interactive session. For some reason cron shows up in ps but at does not. at shows up in the process tree, but cron does not. Thus several tests are required to figure out the parent

#!/bin/sh -

SESSION_ID=$(ps -j h $$ | awk '{print $3}')         # Get session id
# look for atd in the process table
PS=$(ps -s $SESSION_ID | sed -n '/atd/p' | sed -e '1q')
[ -n "$PS" ] && PARENT='AT daemon'              # if found

# look for CRON in the process table
PS=$(ps aux | grep $PPID | grep -v grep | grep CRON)
[ -n "$PS" ] && PARENT='CRON daemon'            # if found

# look for the tty in the process table
TTY=$(ps -j h $$ | awk '{print $4}')
[ "$TTY" == '?' ] || PARENT='Interactive shell'     # if found
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜