Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 获取subshell命令的pid_Bash_Shell_Init_Pid_Subshell - Fatal编程技术网

Bash 获取subshell命令的pid

Bash 获取subshell命令的pid,bash,shell,init,pid,subshell,Bash,Shell,Init,Pid,Subshell,我正在尝试为java程序编写一个init服务脚本。我在init脚本中有以下内容 $USER = awesomeuser $PROGRAM_CMD = "java -server com.test.TestClass" $PROGRAM_LOG = "/var/log/awesome_log" sudo -u $USER nohup $PROGRAM_CMD >> $PROGRAM_LOG 2>&1 </dev/null & server_pid=$!

我正在尝试为java程序编写一个init服务脚本。我在init脚本中有以下内容

$USER = awesomeuser

$PROGRAM_CMD = "java -server com.test.TestClass"

$PROGRAM_LOG = "/var/log/awesome_log"

sudo -u $USER nohup $PROGRAM_CMD >> $PROGRAM_LOG 2>&1 </dev/null &
server_pid=$!
echo $server_pid > $pidfile
$USER=awesomeuser
$PROGRAM\u CMD=“java-server com.test.TestClass”
$PROGRAM_LOG=“/var/LOG/awesome_LOG”
sudo-u$USER nohup$PROGRAM\u CMD>>$PROGRAM\u LOG 2>&1$pidfile
我得到的是父进程的pid,但我确实希望java进程的pid在子shell中运行

我是否可以构造命令,以便返回subshell命令pid


谢谢

关于使用另一个脚本的内容:

findpid.sh

然后在脚本中调用findpid.sh。调用java时可以使用时间戳,以确保使用
ps
识别正确的进程

#!/bin/bash
USER=awesomeuser
TIME=`date +"%s"`
PROGRAM_CMD="java -server com.test.TestClass java -Dtime=${TIME}"
PROGRAM_LOG="awesome_log"

bash findpid.sh "${USER}" "${PROGRAM_CMD}" &
sudo -u $USER nohup $PROGRAM_CMD >> $PROGRAM_LOG 2>&1 </dev/null &
wait
#/bin/bash
USER=awesomeuser
时间=`date+%s“`
PROGRAM_CMD=“java-server com.test.TestClass java-Dtime=${TIME}”
PROGRAM\u LOG=“awesome\u LOG”
bash findpid.sh“${USER}”“${PROGRAM\u CMD}”&

sudo-u$USER nohup$PROGRAM\u CMD>>$PROGRAM\u LOG 2>&1使用其他脚本有什么好处:

findpid.sh

然后在脚本中调用findpid.sh。调用java时可以使用时间戳,以确保使用
ps
识别正确的进程

#!/bin/bash
USER=awesomeuser
TIME=`date +"%s"`
PROGRAM_CMD="java -server com.test.TestClass java -Dtime=${TIME}"
PROGRAM_LOG="awesome_log"

bash findpid.sh "${USER}" "${PROGRAM_CMD}" &
sudo -u $USER nohup $PROGRAM_CMD >> $PROGRAM_LOG 2>&1 </dev/null &
wait
#/bin/bash
USER=awesomeuser
时间=`date+%s“`
PROGRAM_CMD=“java-server com.test.TestClass java-Dtime=${TIME}”
PROGRAM\u LOG=“awesome\u LOG”
bash findpid.sh“${USER}”“${PROGRAM\u CMD}”&
sudo-u$USER nohup$PROGRAM\u CMD>>$PROGRAM\u LOG 2>&1而不是

sudo -u $USER nohup $PROGRAM_CMD >> $PROGRAM_LOG 2>&1 </dev/null &
而不是

$USER = awesomeuser
$PROGRAM_CMD = "java -server com.test.TestClass"
$PROGRAM_LOG = "/var/log/awesome_log"
而不是

sudo -u $USER nohup $PROGRAM_CMD >> $PROGRAM_LOG 2>&1 </dev/null &
而不是

$USER = awesomeuser
$PROGRAM_CMD = "java -server com.test.TestClass"
$PROGRAM_LOG = "/var/log/awesome_log"

如果没有shell支持,就无法做到这一点,而bash也没有提供正确的原语。改变感兴趣的进程以输出或存储自己的PID是正确的方法

如果无法更改应用程序代码,可以使用俗气的包装,如:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

/*
 * pidder cmd args - launch cmd with args and print its pid
 */

int
main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "usage: pidder command [args]\n");
        exit(2);
    }

    switch(fork()) {
        case -1:
            perror("fork");
            exit(2);
        case 0:
            printf("%d\n", getpid());
            /* launch cmd with path search if relative path */
            execvp(argv[1], argv+1);
            perror("exec");
            exit(1);
        default:
            exit(0);
    }

}
#包括
#包括
#包括
#包括
/*
*pidder cmd args-使用args启动cmd并打印其pid
*/
int
main(int argc,char*argv[])
{
如果(argc<2){
fprintf(stderr,“用法:pidder命令[args]\n”);
出口(2);
}
开关(fork()){
案例1:
佩罗尔(“福克”);
出口(2);
案例0:
printf(“%d\n”,getpid());
/*如果是相对路径,则使用路径搜索启动cmd*/
execvp(argv[1],argv+1);
perror(“执行董事”);
出口(1);
违约:
出口(0);
}
}

如果使用此命令,请注意,
$./pidder some_命令
将与
$some_命令
有细微的区别,一个简单的示例是,在第一种情况下,PPID将不是调用shell

如果没有shell支持,就无法做到这一点,而bash也没有提供正确的原语。改变感兴趣的进程以输出或存储自己的PID是正确的方法

如果无法更改应用程序代码,可以使用俗气的包装,如:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

/*
 * pidder cmd args - launch cmd with args and print its pid
 */

int
main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "usage: pidder command [args]\n");
        exit(2);
    }

    switch(fork()) {
        case -1:
            perror("fork");
            exit(2);
        case 0:
            printf("%d\n", getpid());
            /* launch cmd with path search if relative path */
            execvp(argv[1], argv+1);
            perror("exec");
            exit(1);
        default:
            exit(0);
    }

}
#包括
#包括
#包括
#包括
/*
*pidder cmd args-使用args启动cmd并打印其pid
*/
int
main(int argc,char*argv[])
{
如果(argc<2){
fprintf(stderr,“用法:pidder命令[args]\n”);
出口(2);
}
开关(fork()){
案例1:
佩罗尔(“福克”);
出口(2);
案例0:
printf(“%d\n”,getpid());
/*如果是相对路径,则使用路径搜索启动cmd*/
execvp(argv[1],argv+1);
perror(“执行董事”);
出口(1);
违约:
出口(0);
}
}

如果使用此命令,请注意,
$./pidder some_命令
将与
$some_命令
有细微的区别,一个简单的示例是,在第一种情况下,PPID将不是调用shell

$USER=awesomeuser
——这真的是
bash
?看起来像PHP。你需要学习基本的
bash
语法。变量赋值类似于
USER=awesomuser
——变量前面没有
$
,并且
=
周围没有空格。这不是子shell。这是一个。
$USER=awesomeuser
——这真的是
bash
?看起来像PHP。你需要学习基本的
bash
语法。变量赋值类似于
USER=awesomuser
——变量前面没有
$
,并且
=
周围没有空格。这不是子shell。这是一个。工作正常,但可能存在竞争条件:进程在调用此序列时可能已经死亡。
ps | grep name
很有可能产生错误的进程。@msw您是对的。如果java启动两次,将检索不正确的pid my。通过在java调用中包含时间戳,ps将有更好的机会识别正确的进程。工作正常,但可能存在竞争条件:在调用此序列时,进程可能已经死亡。
ps | grep name
很有可能产生错误的进程。@msw您是对的。如果java启动两次,将检索不正确的pid my。通过在java调用中包含时间戳,ps将有更好的机会识别正确的进程?为什么你认为shell不能被用来做正确的事情?你有没有检查过我下面的答案?你为什么认为不能用shell来做正确的事情?