Почему не делает системы (), работают при вызове в цикле с командами комнаты и CD?

Я начал использовать Linux недавно, таким образом, моя программа только для изучения. Однако вот мой код:

#include <stdio.h>
#include <stdlib.h>

int main () {

FILE *fin;
char buf[200];

fin = fopen("provaMake.txt", "r");
if (fin==NULL) {
    fin = fopen("/home/giorgio/Desktop/provaMake.txt", "r");
    if (fin==NULL) {
        printf("finError\n");
        exit(1);
    }
}

while(fgets(buf, 200, fin) != NULL) {

    system(buf);

}

fclose(fin);

}

И вот provaMake.txt файл:

cd /home/giorgio/Desktop/a
rm -f pippo.txt
cd /home/giorgio/Desktop

Когда я выполняю его использование:

$gcc provaMake.c -o provaMake.o
$./provaMake.o

Это не удалило pippo.txt (это находится в a каталог внутри Desktop).

Я делаю что-то не так в коде? Я повторяю, что пытаюсь учиться, поэтому объясните это мне (или перенаправьте меня, где я могу учиться).

1
задан 6 November 2019 в 02:19

2 ответа

system() выполнения команда в оболочке. Та оболочка является новым процесс . Это - дочерний процесс Вашей программы C. cd управляют, изменяет текущий каталог для процесса оболочки, в котором он выполняется. Это наследовано дочерними процессами той оболочки. Но это не влияет на текущий каталог для родительских процессов.

Вы звоните system() три раза. Каждый раз процесс оболочки запускается, он выполняет команду, и он заканчивается. cd в одном вызове к [1 113] не влияет на текущий каталог в отдельных вызовах к [1 114].

, Если необходимо использовать system(), затем лучшее решение для Вас, проблема могла бы быть должна избежать cd и просто сделать все в одной команде. Но это будет только работать, если можно измениться provaMake.txt. В частности, это должно работать содержанием [1 118]:

rm -f /home/giorgio/Desktop/a/pippo.txt

, Если Вы должны использовать system(), но не можете или не хотят изменяться provaMake.txt, или если Вы конкретно интересуетесь тем, как использовать system() для выполнения всех команд в файле в том же процессе оболочки , затем можно передать system() трудно кодированная команда, которая запускает новую оболочку и выполняет все команды в том файле в той же оболочке. Например, Ваша программа C могла использовать код:

system(". /home/giorgio/Desktop/provaMake.txt");

Вы заменили бы примерно свою всю программу той командой. Никакой буфер не необходим, потому что Ваша программа C самостоятельно не читает из файла. Точно так же никакой fopen() вызов необходим. Оболочка - то, что открывается, читает из и выполняет команды из файла - это - действие . встроенный, который присутствует, когда любая оболочка стиля Границы используется. (system() использование sh, который является оболочкой стиля Границы, как bash.)

Примечание, что, если Ваша программа C впоследствии полагается или иначе наблюдает свой текущий рабочий каталог, который все еще будет незатронут cd выполненные команды (так же, как в Вашем исходном коде), потому что они только работали в оболочке.

<час>

иногда разумно сделать вещи изобретенным способом для изучения целей, таким образом, я не хочу говорить Вам не писать программу C, которая использует system() для выполнения всех команд оболочки из файла один за другим. Однако в случае, куда Ваша фактическая цель состоит в том, чтобы просто выполнить все команды в файле, Вам не нужна программа C. Можно просто использовать оболочку:

  • , Если Вы хотите выполнить команды в Вашем текущий процесс оболочки, так, чтобы его среда была затронута - например, так, чтобы эффекты [1 130] команды сохранились впоследствии - затем, можно просто работать:

    . /home/giorgio/Desktop/provaMake.txt
    
  • , Если Вы хотите выполнить команды в новый оболочка, так, чтобы среда текущей оболочки не была затронута, затем передают название файла как командная строка к оболочке:

    bash /home/giorgio/Desktop/provaMake.txt
    

    можно скорректировать ту команду, если оболочка Вы используете или хотите использовать, не удар. Например:

    sh /home/giorgio/Desktop/provaMake.txt
    
  • можно хотеть составить список команд сам быть исполняемым файлом. Чтобы сделать это, добавьте, что-то вроде этого к началу (корректируйтесь согласно тому, какая оболочка должна использоваться для интерпретации его):

    #!/bin/bash
    

    И изменение его полномочия так, чтобы это был исполняемый файл путем выполнения команды:

    chmod +x filename

    Замена filename с фактическим именем файла, такой как [1 132].

    Затем можно петлять как любая программа:

    ./provaMake.txt  # when you're in the directory that contains it
    
    /home/giorgio/Desktop/provaMake.txt  # from anywhere
    

В том последнем случае особенно, необычно назвать файл с .txt суффикс. В целом распространено, что файлы, содержание которых будет выполнено с . встроенный, называют с .sh суффикс, и что файлы, которые будут отмечены исполняемый файл и выполнены как сценарии, называют без суффикса. (Имя файла не имеет значения, что касается оболочки и операционная система, все же.)

1
ответ дан 7 December 2019 в 14:57

Я не знаю, почему это не работает на Вас, когда я попробовал что-то подобное, это работало.

Так или иначе, добавляя приблизительно printf операторы могут быть очень полезными для понимания то, что делает программа. Например, попытайтесь добавить эту строку в своем цикле с условием продолжения только перед эти system вызов:

printf("Now calling system() with buf = %s\n", buf);

Затем компиляция и выполненный снова и взгляд на вывод, надо надеяться, который должен помочь Вам понять то, что происходит.

0
ответ дан 7 December 2019 в 14:57

Другие вопросы по тегам:

Похожие вопросы: