简体   繁体   English

为什么我的 bash 脚本在我的 C 程序中不起作用?

[英]Why does my bash script not work in my C program?

My program takes an arbitrary number of words from the user and stores them in a double pointer **stringArr .我的程序从用户那里获取任意数量的单词并将它们存储在双指针**stringArr These values are then concatenated into a string which is then passed into a bash script I have.然后将这些值连接成一个字符串,然后将其传递到我拥有的 bash 脚本中。

The problem I have is that the bash script doesn't echo the command I want it to, and I am unsure why.我遇到的问题是 bash 脚本没有echo显我想要的命令,我不确定为什么。

string = malloc(N * sizeof(char));

    for (int j = 0; j < N; j++) {
        strcat(string, stringArr[j]);
        strcat(string, " ");
    }

puts("\n\nYour input sorted in alphabetical order:");
    if (fork() == 0) {
        execl("./sortString.sh", "sortString.sh", string, NULL);
    }
#!/bin/bash
for NAME in "$@"
do
VAR=$VAR" "$NAME
done
echo $VAR | tr ’ ’ ’\n’ | sort | tr ’\n’ ’ ’

Is there something I am missing?有什么我想念的吗?

Note: the bash script is in the same directory as the program;注意:bash脚本和程序在同一个目录下; the program works in regards to taking user input and it putting into the string string .该程序的工作原理是接收用户输入并将其放入字符串string

If you want to try out the bash script, an example of string I have passed through is: "one two three " (there is a space after 'three').如果你想尝试 bash 脚本,我传递的一个string示例是:“一二三”('三'后面有一个空格)。

You cannot use the exec() family of functions to execute a shell script directly;不能使用exec()系列函数直接执行 shell 脚本; they require the name of a proper executable.它们需要适当的可执行文件的名称。 If you check the return value of your execl() call, I'm sure you'll see an error ( -1 ), and errno will probably have been set to ENOEXEC .如果您检查execl()调用的返回值,我确定您会看到错误 ( -1 ),并且errno可能已设置为ENOEXEC

You could try using system() instead, but it is generally frowned upon because you'd need to build a full (single) command string, and making sure that everything is properly escaped and such is error-prone.您可以尝试使用system()代替,但通常不赞成使用它,因为您需要构建一个完整的(单个)命令字符串,并确保所有内容都正确转义,这很容易出错。

Instead, I'd recommend that you give "/bin/sh" or "/bin/bash" as the first argument to exec() .相反,我建议您将"/bin/sh""/bin/bash"作为exec()的第一个参数。 Then, the args to sh would need to be the path of your script, and then the args that your script will use.然后, sh的 args 需要是脚本的路径,然后是脚本将使用的 args。

(this is what your shell does automatically when you run a script; it reads the #! line, and executes "/bin/bash your-script your-args...") (这是您的 shell 在您运行脚本时自动执行的操作;它读取#!行,并执行“/bin/bash your-script your-args...”)

Your string allocation is too small.您的string分配太小。 You're allocating space for N chars, but you're strcat ing N spaces into it, plus whatever is in your stringArr (which I assume is not full of empty strings).你N个字符分配空间,但你strcat荷兰国际集团n个空格进去,再加上无论是在你的stringArr (我假设是不完全空字符串的)。

Even then, you will have just one big string of args, but exec() wants them separated.即便如此,您也只有一大串参数,但exec()想要将它们分开。 Think of it like if you point quotes around all the args in bash;把它想象成如果你在 bash 中的所有参数周围加上引号; you get just one big argument, which contains spaces.你只会得到一个包含空格的大参数。

After you fix that (so that you have an array of strings rather than just one big one), you will run into problems with execl() .在你解决这个问题后(这样你就有了一个字符串数组而不是一个大字符串),你会遇到execl()问题。 It takes the arguments separately, but you're trying to send one big array of them.它分别接受参数,但您试图发送其中的一大组参数。 You'll want execv() instead, which accepts an array of strings for the argument list.您将需要execv()代替,它接受参数列表的字符串数组。 Remember that the first string in that list must be your script path.请记住,该列表中的第一个字符串必须是您的脚本路径。

Are you sure this wouldn't be easier to do with qsort() ?您确定使用qsort()不会更容易吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM