저는 터미널에서 보편적으로 사용할 목적으로 bash 스크립트를 직접 작성하려고 합니다. 애플리케이션을 백그라운드 프로세스로 시작하고 해당 stderr 출력을 삭제해야 합니다. 이것이 내가 얻는 것입니다:
for app in $@; do
$app 2>/dev/null
done
인수 없이 기본 애플리케이션을 실행하는 것처럼 보이지만 script.sh firefox gedit
다음을 수행하지 못합니다.
script.sh "vlc video.mp4"
내 질문은: 매개변수/파일을 입력으로 사용하는 응용 프로그램을 처리하기 위해 이 기본 스크립트를 어떻게 향상시킬 수 있습니까? 어쩌면 내가 사용할 수 있는 도구가 이미 있을 수도 있습니다.
답변1
두 가지 질문이 있습니다:
$@
따옴표 없이 사용하세요 .이렇게 하면 스크립트 호출에서 동일한 인용 문자열 내에 있더라도 루프가 두 개의 별도 항목으로 반복됩니다
vlc
.video.mp4
변수에 명령을 사용합니다.
명령이 단일 간단한 명령보다 더 복잡한 경우에는 작동하지 않습니다.
eval
주어진 문자열로 변경해야 합니다 .
이를 염두에 두고 스크립트는 다음과 같을 수 있습니다.
#!/bin/sh
for cmd do # or: for cmd in "$@"; do
eval "$cmd" 2>/dev/null
done
불러라
./script 'echo "hello world"' 'vim "$HOME/.profile"' 'tr a-z A-Z <"$HOME/.profile" | grep -c EXPORT'
먼저 실행되고 완료되면 두 번째 명령에 지정된 파일을 편집하기 위해 echo "hello world"
열립니다 . vim
마지막 명령은 더 복잡하지만 우리가 그것을 사용하고 있다는 사실에 의해 처리됩니다(단순히 모든 알파벳 문자를 대문자로 변경하고 문자열이 파일에 나타나는 횟수를 계산합니다 eval
). 세션이 종료 EXPORT
되면 실행됩니다.vim
이것으로 당신도 할 수 있습니다
./script 'd=$HOME' 'ls "$d"'
즉, 후속 명령에 사용되는 변수를 설정합니다. 이는 호출된 명령이 eval
스크립트와 동일한 환경에서 실행되기 때문에 작동합니다 . 질문 제목에서 알 수 있듯이 명령을 백그라운드 작업으로 시작하면 작동하지 않습니다.
답변2
현재 스크립트가 각 인수를 별도의 애플리케이션으로 처리하도록 지시하고 있습니다. 그래서 당신은 실행 중입니다 :
$ vlc
그 다음에:
$ video.mp4
스크립트를 다음과 같이 만들어야 합니다.
#!/bin/bash
$@ 2>/dev/null
제 생각에는 어느 것이 함수로서 더 나은가요?
func_name() {
$@ 2>/dev/null
}
참고: 이렇게 하면 한 번에 하나의 명령만 실행할 수 있습니다. 원래 의도가 한 번에 여러 명령을 스크립트에 전달하려는 것인지 확실하지 않습니다. 그렇다면 삭제하겠습니다.