스크립트를 통해 bash 인스턴스 제어(강력한 방식)

스크립트를 통해 bash 인스턴스 제어(강력한 방식)

일부 (최종적으로 대화형) 스크립트(예: Python)를 사용하여 강력한 방식으로 일부 bash 프로그램(로컬 또는 ssh)을 제어하고 싶습니다. 명령을 보내고, 실행이 끝나면 명령의 stdout/stderr과 명령의 종료 코드를 가져오고 싶습니다. bash 명령은 외부 사용자가 실시간으로 선택하므로 어떤 명령이든 가능합니다.

내가 원하는 것을 이해하기 위해 함수를 제공하고 싶습니다(프로그래밍 언어는 중요하지 않음).

def send_command(command):
    # how to implement ????
    return (stdin_output, stderr_output, exit_code)

이렇게 하면 다음과 같이 실행할 수 있습니다.

(o,e,ex) = send_command("pwd")
print("The output of your last command is ", o)
(o,e,ex) = send_command("cd /tmp")
(o,e,ex) = send_command("pwd")
print("The output of your last command is ", o)

그러면 다음이 생성됩니다.

The output of your last command is /home/me/
The output of your last command is /tmp/

command또한, 누구도 내 Python 스크립트를 "망칠" 수 없도록 하고 실제로는 완료되지 않았는데도 명령이 완료되었다고 믿게 만들고 싶습니다 . 예를 들어, 나는 그가 따르는 모든 명령을 기록하는 것을 원하지 않으므로 다음 코드는 첫 번째 줄에서 영원히 차단되어야 하며(첫 번째 명령은 무한 루프입니다) 두 번째 줄을 호출하지 않아야 합니다.

send_command("echo $PS1; <malicious command that loops forever and sends all the next inputs to a webserver>")
send_command("echo mysecretpassword") # This line should never be executed

내가 시도한 것:

한 가지 옵션은 매번 새로운 bash 인스턴스를 실행하고 이 콘솔에서 스크립트를 실행하는 것입니다. 그러나 여기에는 두 가지 단점이 있습니다. 첫째, 매번 처음부터 bash/ssh를 로드하기 때문에 그다지 효율적이지 않습니다. 둘째, bash의 상태(환경, 작업 디렉터리)는 실행될 때마다 새롭습니다. 예: "cd /tmp"를 실행하면 다음 명령에서 집에 있게 됩니다.

내가 본 또 다른 옵션은 expect/ 입니다 pexpect. 이 솔루션의 문제점은 내가 아는 한 출력을 구문 분석하는 것일 뿐이라는 것입니다. 이 구문 분석은 bash 출력의 의미를 잃습니다. 예를 들어 을 기대한다면 $명령이 완료되었는지 확인할 방법이 없으며 명령 자체가 이 텍스트를 작성할 수도 있습니다. 마찬가지로, 프로그램이 완전히 신뢰되지 않으면 상황은 더욱 악화될 수 있습니다. 프로그램이 bash를 가장하고 모든 bash 명령을 읽을 수 있습니다. 복잡한 PS1 설정을 시도할 수도 있지만 이 환경 변수는 명령으로 전달되므로 이 변수(예: "env")를 출력하는 모든 프로그램은 명령을 중단하므로 실제로는 신뢰할 수 있는 솔루션이 아닙니다. 마지막으로, 입력한 마지막 명령에 대한 코드를 출력하는 bash 명령을 실행하고 이 결과를 구문 분석하는 것보다 명령 종료 코드를 얻는 "좋은" 방법이 없습니다.

세 번째 옵션을 놓쳤습니까?

감사해요!

- 편집 - 환경 변수에 대해 알아냈는데 PROMPT_COMMAND내가 아는 한 환경 변수로 전송되지 않습니다. 하지만 여전히 쉘에서 직접 읽을 수 있는 쉬운 방법이 있으므로 echo그다지 강력하지도 않습니다.

$ PS1=""
PROMPT_COMMAND='echo -n "Prompt MYSECRETNUMBERSETBYEXPECT (last exit $?) "'                             
Prompt MYSECRETNUMBERSETBYEXPECT (last exit 0) ls /tmp/o
file.txt
Prompt MYSECRETNUMBERSETBYEXPECT (last exit 0) rm /tmp/a/donotexist
rm: impossible de supprimer '/tmp/a/donotexist': No such file or directory
Prompt MYSECRETNUMBERSETBYEXPECT (last exit 1) env | grep SECRET
Prompt MYSECRETNUMBERSETBYEXPECT (last exit 1)

- 편집 2 - 더욱 강력해 보이는 또 다른 솔루션은 임의의 비밀 힌트를 사용한 pexpect다음 다음을 포함하는 것 입니다 command.

PS1=""; <command>; PS1="My secret PS1 61547851396512fdsqjklqdf (last code $?) >>$ "

(이 코드는 명령이 프롬프트 값에 액세스할 수 없도록 명령 앞/뒤에 PS1 비밀 프롬프트를 삭제/다시 생성합니다.) 원하는 경우 하위 쉘을 생성 하지 않고도 다음 <command>으로 대체하여 출력을 파일로 리디렉션할 수도 있습니다 (공백과 세미콜론을 잊지 마세요). { <command>; } > /tmp/out.stdout 2> /tmp/out.stderr이것이 진행하는 가장 좋은 방법입니까?

답변1

당신은 사용해 볼 수 있습니다sysdig, 이는 기본적으로 시스템용 스파이웨어입니다.
~에서sysdiog 위키다음을 사용하여 stdout프로세스 이름에서 관찰 할 수 있습니다 cat.

sysdig -s4096 -A -c stdout proc.name=cat

foo다음 이름의 사용자가 실행한 모든 명령을 관찰할 수도 있습니다.

sysdig -c spy_users user.name=foo

이 StackExchange 질문을 참조할 수도 있습니다.

https://stackoverflow.com/questions/54771786/record-bash-interaction-saving-stdin-stdout-seperately

당신을 위해 생각할 것이 많습니다.

관련 정보