如果子进程调用 exec,它将终止并使用相同的 pid 创建一个新进程。
wait() 函数会等待子进程终止还是孙进程终止?
语境
我想在我的网站后端执行命令行调用。如果此命令行调用失败,我想捕获错误并引发新的自定义错误。
我尝试抛出错误如下:
async function someFunction(): Promise<void> {
...
const result = exec(`some command`);
result.on('error', (error) => {
console.log(error.message);
throw error;
});
}
Run Code Online (Sandbox Code Playgroud)
和
async function someFunction(): Promise<void> {
...
exec(`some command`, (error) => {
if (error) {
throw error;
}
});
}
Run Code Online (Sandbox Code Playgroud)
并像这样抓住它:
try {
await someFunction();
} catch (e) {
...
throw new Error('Meaningfull error')
}
Run Code Online (Sandbox Code Playgroud)
问题
但代码永远不会到达 catch 块,因为它会在我到达抛出错误时关闭。
Error: Command failed: some Command: Kommando nicht gefunden. //(Command not found)
at ChildProcess.exithandler (node:child_process:398:12)
at ChildProcess.emit (node:events:527:28)
at …Run Code Online (Sandbox Code Playgroud) 我仍然是PHP的新手,所以请原谅我,如果我在这里遗漏了一些明显的东西.
所以,我正在调用一些产生文本行的后端脚本,我想我会修补exec它以确保它正常工作.当然,在(Linux)shell中,一个简单的多行输出命令是类似的
echo a;echo b;echo c
Run Code Online (Sandbox Code Playgroud)
当然,这会产生人们的期望:
a
b
c
Run Code Online (Sandbox Code Playgroud)
那么,为什么我在exec下面跑时会得到额外的"c" ?
输入:
exec("echo a;echo b;echo c",$output,$return);
echo("return: $return\n");
echo("count: ". count($output) . "\n");
foreach($output as $i)
{print "$i\n";}
var_dump($output);
Run Code Online (Sandbox Code Playgroud)
输出:
return: 0
count: 4
a
b
c
c
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
[3]=>
string(1) "c"
}
Run Code Online (Sandbox Code Playgroud)
现在,我知道exec返回处理的最后一行,但我没有回显返回值exec.更令人费解的是,如果我让字符串更"随机",它似乎正常工作:
jmaney> php -r 'exec("echo asfd;echo asdfasf;echo grrrr",$output,$return);echo("return: $return\n");echo("count: ". count($output) . "\n");foreach($output as $i){print "$i\n";}var_dump($output);'
return: 0 …Run Code Online (Sandbox Code Playgroud) 我真的很喜欢这个调试帮助.我从早上起凌晨4点就开始研究这个问题了.(我想在7个小时[上午11点]提供这个)
main.c中的所有东西都可以工作,但是当我创建一些子进程来运行带有execl的compute.c的编译文件时,它不会这样做并发送错误"Bad Address".
我已经附加了3个带有main.c和compute.c的pastebin链接以及一个包含我在下面提到的表的txt文件.
该程序假设从一个名为pinakes.txt的文件中读取带有整数的2个表,然后使用POSIX的共享内存API将这些表放在共享内存中并创建进程以计算它们的"行*列"总和并放置该总和在另一张桌子里.
sum += A[row][i] * B[i][column] = C[row][column]
Run Code Online (Sandbox Code Playgroud)
直到main.c下面的行应该正常工作(我调试了很多次).
ppid = getpid();
Run Code Online (Sandbox Code Playgroud)
main.c http://pastebin.com/iMCefaLZcompute.c http://pastebin.com/Ejp214Uppinakes.txt http://pastebin.com/h8yKXFvv
编译然后运行
./main pinakes.txt
Run Code Online (Sandbox Code Playgroud)
188行代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>
int pinA_X = 0, pinA_Y = 0, pinB_X=0, pinB_Y=0;
int pinA[10][10], pinB[10][10], pinC[10][10];
main(int argc, char *argv[]){
int pid, ppid;
FILE *stream;
// general variables
int i, c, j, rc, converted, …Run Code Online (Sandbox Code Playgroud) 我有这个PHP代码,从浏览器调用时拒绝工作,但是当我从Putty运行它时它工作得很好:
exec('rdiff patch "/full-path/file-1.bin" "/full-path/file-2.bin" "/full-path/output.bin"');
Run Code Online (Sandbox Code Playgroud)
我双重检查文件夹权限(nobody:nobody 0777),rdiff运行权限(设置为root:root 0755,我将它们更改为nobody:nobody 0777但它没有工作),我甚至将文件权限更改为0777 /"将它们归结为" "对任何人来说,根本没用
我很确定这没什么,只是我无法弄清楚什么是错的,我正在使用标准的亚马逊unix EC2实例
<?php
//ENTER THE RELEVANT INFO BELOW
$mysqlDatabaseName ='db123456789';
$mysqlUserName ='dbo123456789';
$mysqlPassword ='myPassword';
$mysqlHostName ='db1234.perfora.net';
$mysqlExportPath ='chooseFilenameForBackup.sql';
//DONT EDIT BELOW THIS LINE
//Export the database and output the status to the page
$command='mysqldump --opt -h' .$mysqlHostName .' -u' .$mysqlUserName .' -p' .$mysqlPassword .' ' .$mysqlDatabaseName .' > ~/' .$mysqlExportPath;
exec($command,$output=array(),$worked);
switch($worked){
case 0:
echo 'Database <b>' .$mysqlDatabaseName .'</b> successfully exported to <b>~/' .$mysqlExportPath .'</b>';
break;
case 1:
echo 'There was a warning during …Run Code Online (Sandbox Code Playgroud) 最近将Strawberry Perl放在Windows 8.1机器上exec
,并发现在git-bash中使用v5.8.8的行为与/bin/perl使用Strawberry的机器不同/c/strawberry/perl/bin/perl.这是我发现的非常简单的脚本(纯粹是在玩的时候偶然$PATH):
#!/usr/bin/env perl
my $comment = "@ARGV" || 'update';
exec "git status; git add -A . ; git status; git commit -m '$comment'; git push";
Run Code Online (Sandbox Code Playgroud)
这与git-bash(/bin/perl)工作正常,但在/c/strawberry/perl/bin/perl发现$PATH以下错误发生时:
git: 'status;' is not a git command. See 'git --help'.
Did you mean this?
status
Run Code Online (Sandbox Code Playgroud)
两种情况下的代码都相同.我的预感是草莓中的perl 5.18改变了exec命令本身的行为,因为它在上下文中解释了它的参数(就像perl喜欢这样做).
我主要担心的是,perl的两个版本在某种程度上使这个相当简单的代码在perl版本之间不兼容,而不是其他一些简单的系统配置问题,甚至可能是草莓发行版本身而不是perl的问题.
如果这是一个perl兼容性问题,我倾向于坚持使用v5.8.8,它完成了我想要Perl为我做的所有事情(在转到另一种语言之前).
execperl语句是否在这些版本之间发生了变化?我在互联网上找不到任何证据.
要重新创建此行为:
在Windows机器上安装git-scm.org:
所以我知道exec*函数之后的所有内容都不会被执行(如果exec*调用当然是成功的话).
我想明白为什么会这样?所以我开发了这个小小的程序
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("A program made to understand execvp\n");
char *cmd[4] = {"ls", "-l","file",NULL};
execvp(cmd[0],cmd);
printf("This will not be printed!!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我所理解的是,bin目录中的可执行命令实际上是可执行程序,因此基本上从我们的程序中调用另一个程序.
而且我确实读到了某个地方
如果成功,exec系统调用不会返回调用程序,因为调用图像丢失.
但这究竟意味着什么,为什么他们不回到调用程序?他们如何回归呢?
我的go语言程序打印"选项-n 1的值不正确,有效范围为1到4294967295".尝试使用下面的代码片段ping时
result , err := exec.Command("ping","-n 1", "-w 1", ip).Output()
fmt.Printf("%s\n", result)
Run Code Online (Sandbox Code Playgroud)
当从Win中的cmd中执行它时,即'ping -n 1 -w 1 8.8.8.8'就可以了
我需要在Python中创建20个变量.这些变量都是需要的,它们最初应该是空字符串,空字符串稍后将被其他字符串替换.我不能在需要时根据需要创建变量,因为我还有一些if/else语句需要检查变量是否仍为空或已经等于其他字符串.
而不是写作
variable_a = ''
variable_b = ''
....
Run Code Online (Sandbox Code Playgroud)
我想到了类似的东西
list = ['a', 'b']
for item in list:
exec("'variable_'+item+' = '''")
Run Code Online (Sandbox Code Playgroud)
此代码不会导致错误,但仍然无法实现我所期望的 - 变量不是使用名称"variable_1"创建的,依此类推.
我的错误在哪里?
谢谢,Woodpicker