BSDから完全なLinuxに移行しています。 Ubuntu 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
また、シェバンラインがあることに注意してください。
#!/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
以下は、オプション処理の2つの例です。まず組み込みシェルを使用し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 -