Скрыть вызов командной строки os.system в скрипте python

У меня есть скрипт Python (myscript.py), который я запускаю на сервере Linux, как показано ниже:

питон myscript.py

В моем скрипте я использую системный вызов, пример ниже:

os.system("./myprogram.pl -x 5 > results.out")

Когда я запускаю myscript.py на сервере всякий раз, когда есть вызов os.system, вызов команды виден на сервере. Есть ли способ скрыть все вызовы команд, чтобы они не отображались при вызове внутри программы (myscript.py)? (Речь не идет о сокрытии вывода, полученного в результате вызовов команд внутри программы)


person sal_x_sal    schedule 14.07.2014    source источник
comment
И зачем это вообще нужно? Пытливые умы хотят знать!   -  person Martijn Pieters    schedule 14.07.2014
comment
Вы можете перезаписать sys.__stdout__ или другие подобные хаки, но я думаю, что лучшим решением было бы использование модуля подпроцесса или даже библиотеки, такой как invoke.   -  person Lyndsy Simon    schedule 14.07.2014
comment
Ах, я подозреваю, что вы имеете в виду, что stdout команды виден. Я на мгновение подумал, что вы хотите скрыть процесс из списка процессов ОС. Это было непонятно.   -  person Martijn Pieters    schedule 14.07.2014
comment
Сервер используется большим количеством людей, и я хотел бы сохранить конфиденциальность своей работы, включая те инструменты, которые я использую.   -  person sal_x_sal    schedule 14.07.2014
comment
@MartijnPieters - на самом деле, я думаю, он действительно хочет сохранить в секрете командную строку процесса.   -  person tdelaney    schedule 14.07.2014
comment
Почему это было закрыто? Плакат ясно показывает, что вывод уже перенаправлен на results.out. Он хочет скрыть процесс от других пользователей (от ps, top и т.д.).   -  person tdelaney    schedule 14.07.2014
comment
@tdelaney: тогда я предлагаю ОП уточнить это в редактировании, после чего его, возможно, можно было бы открыть повторно. Однако, вероятно, есть другие сообщения, которые являются подделкой.   -  person Martijn Pieters    schedule 14.07.2014
comment
@tdelaney: в любом случае, мой близкий голос был на самом деле за «неясно, о чем вы спрашиваете» именно по этой причине; двусмысленность относительно того, что намерение здесь.   -  person Martijn Pieters    schedule 14.07.2014
comment
Есть способы скрыть процесс. Я погуглил (selinux скрывает параметры процесса) и получил это полезное опубликовать среди прочего.   -  person tdelaney    schedule 14.07.2014
comment
спасибо тделаней! @MartijnPieters Я пытался отредактировать пост для уточнения. Кажется, то, что я думаю сделать, сложнее, чем я думал. Я думал, что будет какая-то команда hide/или visible=off, которую я мог бы использовать всякий раз, когда я делаю системный вызов в своем сценарии. Я попытаюсь изучить то, чем поделился tdelaney, но если это слишком сложно, я просто продолжу использовать os.system. Спасибо!   -  person sal_x_sal    schedule 15.07.2014


Ответы (3)


Вы можете использовать канал подпроцесса вместо команды os.system:

import subprocess;

NewPipeObject = subprocess.Popen( [ './myprogram.pl -x 5 > results.out' ],
                                  stdout= subprocess.PIPE,
                                  stderr= subprocess.PIPE );

или вы можете воспользоваться форматом списка аргументов для канала подпроцесса (он добавляет пробел между каждым элементом списка) и представить их следующим образом (что будет легче обобщить):

import subprocess;

NewPipeObject = subprocess.Popen( [ './myprogram.pl',
                                    '-x',
                                    '5',
                                    '>',
                                    'results.out' ],
                                  stdout= subprocess.PIPE,
                                  stderr= subprocess.PIPE );

В любом случае вы подавляете выходные данные от stdout и stderr в объект канала (NewPipeObject).

person Community    schedule 14.07.2014
comment
На самом деле вы не можете передать [ './myprogram.pl -x 5 > results.out' ] в Popen при использовании shell=False, которое используется по умолчанию для Popen. Вы должны передать каждое из них в виде списка: вместо этого Popen(['./myprogram.pl', '-x', '5']). Затем перенаправление stdout на results.out будет выполняться с использованием аргумента ключевого слова stdout, поскольку использование '›' для перенаправления stdout является функцией только оболочки. Другой вариант — использовать shell=True, и в этом случае вы должны передать полную команду в виде строки. - person dano; 15.07.2014

Используйте модуль подпроцесса для создания подпроцесса, поэтому вы не увидите никаких выходных данных из процесса, если вы не читаете напрямую из PIPE.

process = subprocess.Popen(['perl', 'myprogram.pl'], stdout = subprocess.PIPE )
person etr    schedule 14.07.2014

Вы имеете в виду, можете ли вы скрыть команду от отображения в ps, top и других подобных инструментах? Нет.

В некоторых системах myprogram.pl может сама скрывать свою командную строку от появления в ps; например в перле:

$0 = 'new program name';

Это редактирует запись ps, а не удаляет ее. Поскольку он устанавливается новым процессом, возникает состояние гонки, когда кто-то может увидеть его до того, как он будет изменен; и может быть возможно (конечно, для суперпользователя) получить ту же информацию другими способами. Нет безопасного способа полностью скрыть вашу командную строку от других пользователей.

person Colin Phipps    schedule 14.07.2014