head
수정된 스크립트(명령?)를 ~/.bashrc에 추가하겠습니다 . 수동으로 입력하든, 와일드카드에서 파생하든, stdin에서 제공하든 입력을 예상대로 처리합니다. 그러나 에 인수를 제공하는 것을 잊어버리면 headj
터미널이 중단되고 Ctrl-C를 사용하여 다시 시작할 수 없습니다.
echo
다음은 내 코드입니다(디버깅 목적으로 일부 호출 포함).
headj(){
echo "script makes it this far without arguments"
IFS=" " read -r -a input <<< "${@:-$(</dev/stdin)}"
echo "but but crashes before getting here"
#
for i in ${input[@]}; do
echo -e "███████████████████████████████████████████████████████████████████████████████"
echo -e "headj $i start"
head -50 "$i"
done
}
다음과 같이 동작합니다:
$ headj list1
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
$ headj list*
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d
$ ls -1 li* | headj
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d
$ headj
script makes it this far without arguments
그것이 걸려있는 곳입니다.
읽기 입력을 사용해 보았 input=( ${@:-$(</dev/stdin)} )
으나 동일한 오류가 발생했습니다. 오류를 처리하려면 스크립트 시작 부분에 이 코드를 추가하세요.
if [ -z ${*:+x} ]; then
echo "headj requires at least one argument"
return
fi
더 좋은 방법이 있나요? 또, 이런 질문에는 꼭 검색해야 할 키워드가 있나요?
답변1
인수나 잘못된 파이프 없이 실행하고 있고 함수의 stdin에 파일 이름을 쓰고 싶지 않다고 가정하면(그렇게 하는 이유) stdin이 tty인지 확인하는 검사를 추가하겠습니다.
headj() {
local files=()
if [ "$#" -gt 0 ]; then
files=("$@")
elif ! tty >/dev/null; then
readarray -t files
else
echo "Will not read filenames from a tty!" >&2
fi
for file in "${files[@]}"; do
echo "do something with $file..."
done
}
따라서 이것은 작동합니다.
$ ls *.txt |headj
do something with test.txt...
그러나 이것은 다음에 대해 불평합니다.
$ headj
Will not read filenames from a tty!
사용하는 명령 은 read
파일 이름을 공백으로 분할하므로 그렇게 하지 않을 것입니다. 따라서 매개변수 수와 위 배열의 조건이 달라집니다. 줄 바꿈 readarray
으로 구분된 항목 목록을 읽어야 합니다. 이는 파이프로 연결될 ls
때 find
생성되는 항목이지만, 물론 이는 줄 바꿈이 포함된 파일 이름이 작동하지 않음을 의미합니다.
(약간 까다로울 수도 있지만 "$@"
매개변수 <<<
나 작업에서는 여러 단어를 생성해야 하기 때문에 사용하지 않을 것입니다. 그러나 그런 경우에는 그렇게 하지 않습니다. 사용하면 <<< "$*"
의도가 단일 문자열을 변환하는 것임을 더 명확하게 할 수 있습니다 . )
^C가 작동하지 않는 이유에 대해서는 반복할 수 없으며 함수가 그렇게 하도록 되어 있는 것 같지 않습니다.
답변2
방금 bashrc에 기능을 추가하는 방법을 배웠습니다. 고마워요. 문제를 해결하려면 이것을 시도해 보세요.
headj(){
ARG=${1? Error. Please, provide the input file. Example: headj filename}
#echo "script makes it this far without arguments"
IFS=" " read -r -a input <<< "${@:-$(</dev/stdin)}"
#echo "but but crashes before getting here"
#
for i in ${input[@]}; do
echo -e ""`enter code here`
echo -e "headj $i start"
head -50 "$i"
done}
$headj
배쉬: 1: 오류. 입력 파일을 제공해 주세요. 예: headj 파일 이름
파이프의 예
$echo "It works for me." > answer.txt
$ cat answer.txt
이것은 나에게 효과적입니다.
$headj answer.txt | awk '{print $_}'
headj 응답.txt 시작
이것은 나에게 효과적입니다.
headj answer.txt | awk '{print $_}' | sed 's/me./me. It should work for you too./g'
headj 응답.txt 시작
이것은 나에게 효과적입니다. 그것은 당신에게도 효과가 있을 것입니다.