BSD에서 전체 Linux로 전환 중입니다. 우분투 16.04의 스크립트
#!/bin/sh
while (( "$#" )); do
case "$1" in
-i | --ignore-case)
[ $# -ne 2 ] && echo "2 arguments i needed" && exit 1
case_option=-i
;;
-*)
echo "Error: Unknown option: $1" >&2
exit 1
;;
*) # No more options
break
;;
esac
shift
done
# -o, if not, then ...
find $HOME ! -readable -prune -o \
-type f -name "*.tex" -exec grep -l $case_option "$1" {} + | vim -R -
오류는 루프에 있습니다.
sh ./script masi
예상한 것과 동일한 출력을 반환합니다.- 달리기
sh ./script -i masi
. 출력: 빈 파일. 예상 출력: 결과 목록. 스타우트는./script: 2: ./script: 2: not found Vim: Reading from stdin...
.
가능한 오류
while (( "$#" ))
- ...
어떤 이유로 이 옵션을 전혀 사용할 수 없습니다.
getopts로 이동하려는 동기 - terdon의 답변
case_option=""
while getopts "i:" opt; do
case $opt in
i | ignore_case)
[[ $# -ne 2 ] && echo "2 arguments i needed" && exit 1
case_option=-i
;;
-*)
echo "Error: Unknown option: $1" >&2
exit 1
;;
*) # No more options
break
;;
esac
done
find $HOME ! -readable -prune -o \
-type f -name "*.tex" -exec grep -l $case_option "$1" {} + | vim -R -
어디
./script masi
또는 전화를 통해./script -i masi
.
while
사례를 반복하는 방법은 무엇입니까 ?
답변1
dash
sh
or 대신 and 를 사용하여 실행하기 때문에 실패합니다 bash
. Ubuntu에서는 최소한의 POSIX 호환 셸인 /bin/sh
심볼릭 링크입니다 . /bin/dash
가장 간단한 해결책은 스크립트를 실행하는 것인데 bash
예상대로 작동하지 않습니다.
bash ./script masi
또한 Shebang 라인이 있다는 점에 유의하십시오.
#!/bin/sh
즉, 실행할 필요가 없고 sh ./script
실행만 하면 됩니다 ./script
. 대신 bash를 가리키도록 shebang 줄을 변경하십시오 sh
.
#/bin/bash
sh
( Ubuntu에서) 고집한다면 루프를 다음과 같이 변경 dash
해야 합니다 .while
while [ "$#" -gt 0 ]; do
또는 다음을 살펴보고 싶을 수도 있습니다.getopts
.
답변2
getopts
옵션 매개변수를 처리하면 스크립트가 수행하는 작업이 아무런 영향을 미치지 않습니다.
다음은 작은 작업 프레임워크입니다.
case_option=""
while getopts "i:" opt; do
case $opt in
'i')
I_ARG=$OPTARG
;;
'?')
exit 1
;;
esac
done
shift $(($OPTIND - 1))
echo $@
답변3
다음은 옵션 처리에 대한 두 가지 예입니다. 먼저 내장 셸을 사용한 getopts
다음 getopt
from 을 사용합니다 util-linux
.
getopts
옵션은 지원되지 않으며 --long
짧은 옵션만 지원됩니다.
getopt
둘 다 지원됩니다. 사용하시려면 getopt
패키지에 있는 버전을 사용하시면 됩니다 util-linux
.원하지 않는다다른 버전의 getopt를 사용하면 손상되어 사용하기에 안전하지 않으며 작동하는 유일한 버전 util-linux
입니다 .getopt
다행히도 Linux에서는 util-linux
손상된 버전을 특별히 설치하지 않는 한 이 버전만 사용할 수 있습니다.
getopts
이식성이 뛰어나고(대부분 또는 모든 Bourne-Shell 하위 항목에서 작동) 자동으로 더 많은 작업을 수행하지만(예: 설정이 덜 필요하고 해당 옵션에 매개 변수가 있는지 여부에 따라 모든 옵션을 실행 shift
하거나 shift 2
대상으로 지정할 필요가 없음) 성능은 떨어집니다. (긴 옵션은 지원하지 않습니다)
-i
어쨌든 () 옵션을 처리하는 것 외에도 ( ) 옵션과 인수 ( ) 가 필요한 옵션 의 예도 --ignore-case
추가했습니다 . 수행 방법을 보여주는 것 외에 다른 목적은 없습니다.-h
--help
-x
--example
의 경우 getopts
코드는 다음과 같습니다.
#! /bin/bash
usage() {
# a function that prints an optional error message and some help.
# and then exits with exit code 1
[ -n "$*" ] && printf "%s\n" "$*" > /dev/stderr
cat <<__EOF__
Usage:
$0 [-h] [ -i ] [ -x example_data ]
-i Ignore case
-x The example option, requires an argument.
-h This help message.
Detailed help message here
__EOF__
exit 1
}
case_option=''
case_example=''
while getopts "hix:" opt; do
case "$opt" in
h) usage ;;
i) case_option='-i' ;;
x) case_example="$OPTARG" ;;
*) usage ;;
esac
done
shift $((OPTIND-1))
find "$HOME" ! -readable -prune -o -type f -name "*.tex" \
-exec grep -l ${case_option:+"$case_option"} "$1" {} + |
vim -R -
에서 :getopt
util-linux
#! /bin/bash
usage() {
# a function that prints an optional error message and some help.
# and then exits with exit code 1
[ -n "$*" ] && printf "%s\n" "$*" > /dev/stderr
cat <<__EOF__
Usage:
$0 [ -h ] [ -i ] [ -x example_data ]
$0 [ --help ] [ --ignore-case ] [ --example example_data ]
-i, --ignore-case Ignore case
-x, --example The example option, requires an argument.
-h, --help This help message
Detailed help message here
__EOF__
exit 1
}
case_option=''
case_example=''
# getopt is only safe if GETOPT_COMPATIBLE is not set.
unset GETOPT_COMPATIBLE
# POSIXLY_CORRECT disables getopt parameter shuffling, so nuke it.
# parameter shuffling moves all non-option args to the end, after
# all the option args. e.g. args like "-x -y file1 file2 file3 -o optval"
# become "-x -y -o optval -- file1 file2 file3"
unset POSIXLY_CORRECT
OPTS_SHORT='hix:'
OPTS_LONG='help,ignore-case,example:'
# check options and shuffle them
TEMP=$(getopt -o "$OPTS_SHORT" --long "$OPTS_LONG" -n "$0" -- "$@")
if [ $? != 0 ] ; then usage ; fi
# assign the re-ordered options & args to this shell instance
eval set -- "$TEMP"
while true ; do
case "$1" in
-i|--ign*) case_option='-i' ; shift ;;
-x|--exa*) case_example="$2" ; shift 2 ;;
-h|--hel*) usage ;;
--) shift ; break ;;
*) usage ;;
esac
done
find "$HOME" ! -readable -prune -o -type f -name "*.tex" \
-exec grep -l ${case_option:+"$case_option"} "$1" {} + |
vim -R -