제거하고 싶은 패키지 목록이 있습니다. 제거 프로그램은 pkg_deinstall
패키지 목록을 제거 매개변수로 사용하지 않습니다. foreach 루프와 같은 목록에서 어떻게 언로드하나요?
[root@fbsd01 /usr/ports/editors/vim]# pkg_info | grep proto| sed 's/\([a-z0-9]*\).*/\1/'
bigreqsproto
compositeproto
damageproto
fixesproto
fontsproto
inputproto
kbproto
randrproto
renderproto
xcb
xcmiscproto
xextproto
xf86bigfontproto
xineramaproto
이와 유사한 명령이 작동할 것이라고 생각하지만 스트림 대신 매개변수로 목록을 전달해야 합니다.pkg_info | grep proto| sed 's/\([a-z0-9]*\).*/\1/' | head -n 1 pkg_deinstall
어떤 프로그램과 구문을 사용해야 하는지에 대한 단서를 제공해 주시면 도움이 될 것입니다. 개인차가 있기 때문에 정확한 답변을 드리기 어려울 수도 있다는 점을 알고 있습니다. 내 문제가 너무 복잡하다면 누군가가 ls
디렉토리에 있는 파일에 대해 작업을 수행하는 방법을 알려줄 수 있습니다 .
답변1
가장 기본적인 "foreach"의 경우 xargs
일부 매개변수를 읽고 이를 다른 명령줄에 추가합니다. 예를 들어 다음을 시도해 볼 수 있습니다.
> cut -d: -f1 /etc/passwd | xargs -n1 echo user:
-d'\n'
사용자 이름에 공백 문자가 포함될 수 있는 경우 매개변수를 전달해야 합니다 . xargs
동일한 명령에 1개의 인수를 모두 추가하려면 다음을 사용하십시오.
> cut -d: -f1 /etc/passwd | xargs echo users:
보다 일반적인 루프의 경우 다음을 사용할 수 있습니다.
> cut -d: -f1 /etc/passwd | while read i; do echo $i; done
이번에는 $i
하나 이상의 명령 순서 중 어디에나 배치할 수 있습니다. 입력은 한 번에 한 줄씩 읽어 변수에 저장됩니다 i
. ² 행을 분할하여 여러 변수에 저장할 수도 있습니다.
> cut -d: -f1,6 /etc/passwd --output-delimiter=' ' | \
while read i j; do echo home directory of user $i is $j; done
원시 파일 이름을 반복하는 경우 다음이 더 좋습니다(주석 참조).
> for i in *.txt; do echo file: $i; done
—
1. 보다 정확하게는 시스템에서 허용하는 금액입니다. 2. 변수
에 따라IFS
답변2
출력 스트림을 매개변수 목록으로 변환하는 두 가지 주요 방법이 있습니다. 이를 수행하는 빠른(때로는 지저분한) 방법은 를 사용하는 것입니다 xargs
. 기본적으로 표준 입력 스트림을 허용하고 각 입력 줄을 별도의 인수로 사용하여 명령을 실행합니다. 공백 및 기타 문자는 인수로 전달될 때 쉽게 잘못 해석될 수 있으므로 항상 입력 형식에 주의해야 합니다. 그러나 패키지 이름은 비교적 안전합니다. 여기에는 쉘 와일드카드나 개행 문자 등 이상한 문자가 포함되어서는 안 됩니다. 따라서 명령은 다음과 같습니다: [3]
$ pkg_info | grep proto | sed 's/\([a-z0-9]*\).*/\1/' | xargs pkg_deinstall -n
일반적인 상황은 실제로 처리되는 각 라인에 대해 명령을 한 번씩 실행해야 한다는 것입니다. 이 경우 -n
인수가 유용합니다. -n1
한 번에 하나씩 실행할 수도 있고 -n10
10개씩 일괄 실행할 수도 있습니다.
$ [pipline] | xargs -n1 pkg_deinstall -n
이제 자동으로 생성된 매개변수 뒤에 다른 매개변수를 추가해야 한다고 가정해 보겠습니다. 이 경우 "-I"를 사용하여 자동 생성된 인수를 대체할 문자열을 지정할 수 있습니다. 또한 필요할 때 인수 참조와 같은 작업을 수행할 수도 있습니다. 그런 다음 매개변수가 배치되는 위치의 형식을 다음과 같이 지정할 수 있습니다. [1][2]
$ [pipline] | xargs -n1 -I{} pkg_deinstall -n "{}" --trailing-argument
더 많은 제어를 원하거나 각 입력 줄에 대해 여러 명령을 실행하려면 다음 옵션은 다음과 같은 루프를 사용하는 것입니다.
$ [pipline] | while read line; do
echo "Uninstalling $line..."
pkg_deinstall -n "$line"
done
pkg_deinstall
일치하는 glob의 일부로 표현식을 자동으로 사용하므로 언로드하기 위해 전달하는 내용에 주의하세요 . 일부 시스템 구성 요소의 기본 이름을 전달하면 해당 구성 요소뿐만 아니라 이름이 비슷하거나 이에 의존하는 모든 구성 요소가 제거됩니다! 이는 재앙이 될 수 있으므로 항상 키트를 주의 깊게 확인하십시오. 실제로 [3]을 실행 하거나 각 단계를 대화식으로 실행하지 않고도 -n
수행될 작업을 보여주기 위해 시험 실행을 수행하는 데 사용할 수 있습니다 .-i
{}
[1] find 및 기타 유사한 exec 함수가 이 형식을 사용하기 때문에 for를 사용하고 있지만 어떤 고유한 문자열도 사용할 수 있습니다.
[2] pkg_deinstall
명령에는 패턴 뒤에 인수가 없으므로 이는 단지 예일 뿐입니다! [3] 코드를 복사하여 붙여넣으면 실제로는 테스트 실행만 표시하는 것 외에는 아무 작업도 수행하지 않도록 모든 예제에
추가했습니다 .-n
답변3
다른 답변을 무시하지 마십시오. 이것은 또 다른 접근 방식입니다.
for pkg in $( pkg_info | grep proto| sed 's/\([a-z0-9]*\).*/\1/' ) ; do
pkg_deinstall $pkg
done
예문에서 인용문은 악몽이기 때문에 개인적으로 | while read foo ...
인용문을 더 자주 사용하는 경향이 있습니다.