スクリプトにオプションを渡すためにパラメータを解析しようとしています。
ただし、次のエラーが表示されます。 Unexpected option: -u 以下のループを除く:
$ gitpratico -u "<usuario_github>" -p "<repositorio_remoto_github>" -c "comentario criação/alteração repositorio"
Unexpected option: -u
O gitpratico deve ser executado dentro da pasta do projeto somente uma unica vez
Enter: gitpratico [ -u "user_git" | --user ] [ -p "project_name" | --proj ]
[ -c "comemt alter project" | --commit ] [ -h | --help]
Unexpected option: -u
O gitpratico deve ser executado dentro da pasta do projeto somente uma unica vez
Enter: gitpratico [ -u "user_git" | --user ] [ -p "project_name" | --proj ]
[ -c "comemt alter project" | --commit ] [ -h | --help]
Unexpected option: -u
O gitpratico deve ser executado dentro da pasta do projeto somente uma unica vez
Enter: gitpratico [ -u "user_git" | --user ] [ -p "project_name" | --proj ]
[ -c "comemt alter project" | --commit ] [ -h | --help]
この問題をどのように解決できますか?
私は成功せずにgetoptを使ってみました。
SHORT=c:p:u:h
LONG=commit:proj:user:help
OPTS=$(getopt -a -n ${0##*/} --options $SHORT --longoptions $LONG -- "$@")
#!/bin/bash
GIT="$(which git)"
CURL="$(which curl)"
#USER_GIT="${1}"
#PROJECT_NAME="${2}"
<<COMENTARIO
O script "gitpratico_multiuser" foi criado para mais de um usuario que tem acesso
a mesma estação de trablho em horarios diferentes possa usar o script sem
precisar ficar digitando a chave token toda vez que usar o script,
basta colocar a "chave token" de todos os usuarios github e os usuario github
no vetor deste script assim se tivermos tres usuarios
que acessam a maquina em horarios diferentes todos eles tem que
estar configurados no vetor com suas respectivas chaves tokens
na mesma posição em que se encontra o seu usuario no vetor
e o ssh configurado no github entao basta
apenas digitar "gitpratico <username_git> <nome_projeto>" para criar os repositorios.
COMENTARIO
USERS_GIT=("usuario1" "usuario2" "github_usuario3")
## Pegando os hosts dos usuarios githubs em ~/.ssh/config e colocando no Vetor
HOSTS_GITHUB_USERS=($(grep "host-" ~/.ssh/config | sed 's/Host\s//g;'))
#Coloque sua chave token no vetor para verificar
ACESS_TOKEN=("chave1" chave2" "chave_token_github_usuario3")
function help(){
echo
echo "O ${0##*/} deve ser executado dentro da pasta do projeto somente uma unica vez"
echo
echo -e "Usage: ${0##*/} [ -u \"user_git\" | --user ] [ -p \"project_name\" | --proj ]
[ -c \"comemt alter project\" | --commit ] [ -h | --help]
"
echo
}
#SHORT=c:p:u:h
#LONG=commit:proj:user:help
#OPTS=$(getopt -a -n ${0##*/} --options $SHORT --longoptions $LONG -- "$@")
if [ $# -lt 3 ]; then
help
else
##Os c:p:u:user:proj:commit: [obriga a digitar um argumento após a opção]
while getopts c:p:u:user:proj:commit:h,help option
do
case "${option}" in
"-u" |" --user")
USER_GIT="${OPTARG}"
;;
"-p" | "--proj")
PROJECT_NAME="${OPTARG}"
;;
"-c"|"--commit")
COMENTARIO="${OPTARG}"
;;
"-h"|"--help")
help
;;
--)
help
;;
*)
echo "Unexpected option: ${1}"
help
;;
esac
done
for ((i = 0; i < "${#USERS_GIT[@]}"; i++))
do
if [[ "${USERS_GIT[$i]}" == "${USER_GIT}" ]]; then
#Criando os repositprios remotamente sem logar no github
${CURL} -i -H "Authorization: token ${ACESS_TOKEN[$i]}" -d "{\"name\":\"${PROJECT_NAME}\",\"private\":false}" https://api.github.com/user/repos
if [[ "${PROJECT_NAME}" != "${PWD[@]/*\/}" ]]; then
mkdir ${PROJECT_NAME}
cd ${PROJECT_NAME}
#Inicializa o repositório
${GIT[@]/*\/} init
##Cria um README no projeto
echo "## README ${PROJECT_NAME}" >> README.md
echo "### PROJETO criado com o script gitpratico" >> README.md
## Adiciona todos os arquivos existentes na pasta
${GIT[@]/*\/} add .
#echo "Digite um comentário sobre o que você fez no projeto: "
#echo
#read -p "Entre com o comentario: " COMENTARIO
##Comitando o projeto
${GIT[@]/*\/} commit -m "${COMENTARIO}"
#Modifica o branch atual criado pelo commit
${GIT[@]/*\/} branch -M main
#Apos fazer qualquer alteração estas configurações permiten fazer apenas "git push" no projeto
#Sem precisar digitar toda vez: git push [email protected]:$USERS_GIT/${PROJECT_NAME}.git main
#Todos os repositórios criados com o script terão "branch master"
echo "[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote \"origin\"]
url = git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch \"main\"]
remote = origin
merge = refs/heads/main"> .git/config
echo "Copie e cole seu token caso nescessário ou digite a senha configurada na chave ssh do github"
echo
${GIT[@]/*\/} push git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git main
elif [[ ${PROJECT_NAME} == ${PWD[@]/*\/} ]]; then
README="$(ls -1 README.md 2> /dev/null)"
#Inicializa o repositório
${GIT[@]/*\/} init
if [ -z "${README}" ]; then
##Cria um README caso o projeto nao tenha nada na pasta ainda
echo "## README ${PROJECT_NAME}" >> README.md
echo "### PROJETO criado com o script gitpratico" >> README.md
else
echo "### PROJETO criado com o script gitpratico" >> README.md
fi
## Adiciona todos os arquivos existentes na pasta
${GIT[@]/*\/} add .
#echo "Digite um comentário sobre o que você fez no projeto: "
#echo
#read -p "Entre com o comentario: " COMENTARIO
##Comitando o projeto
${GIT[@]/*\/} commit -m "${COMENTARIO}"
#Modifica o branch atual criado pelo commit
${GIT[@]/*\/} branch -M main
#Apos fazer qualquer alteração estas configurações permiten fazer apenas "git push" no projeto
#Sem precisar digitar toda vez: git push [email protected]:${USER_GIT}/${PROJECT_NAME}.git main
#Todos os repositórios criados com o script terão "branch master"
echo "[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote \"origin\"]
url = git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch \"main\"]
remote = origin
merge = refs/heads/main"> .git/config
echo "Copie e cole seu token caso nescessário ou digite a senha configurada na chave ssh do github"
echo
${GIT[@]/*\/} push git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git main
fi #Fim PWD
fi #Fim USERS_GIT
done #Fim for
私のスクリプトは次のように変更されました。
#!/bin/bash
GIT="$(which git)"
CURL="$(which curl)"
#USER_GIT="${1}"
#PROJECT_NAME="${2}"
<<COMENTARIO
O script "gitpratico_multiuser" foi criado para mais de um usuario que tem acesso
a mesma estação de trablho em horarios diferentes possa usar o script sem
precisar ficar digitando a chave token toda vez que usar o script,
basta colocar a "chave token" de todos os usuarios github e os usuario github
no vetor deste script assim se tivermos tres usuarios
que acessam a maquina em horarios diferentes todos eles tem que
estar configurados no vetor com suas respectivas chaves tokens
na mesma posição em que se encontra o seu usuario no vetor
e o ssh configurado no github entao basta
apenas digitar "gitpratico <username_git> <nome_projeto>" para criar os repositorios.
COMENTARIO
USERS_GIT=("usuario1" "usuario2" "github_usuario3")
## Pegando os hosts dos usuarios githubs em ~/.ssh/config e colocando no Vetor
HOSTS_GITHUB_USERS=($(grep "host-" ~/.ssh/config | sed 's/Host\s//g;'))
#Coloque sua chave token no vetor para verificar
ACESS_TOKEN=("chave1" "chave2" "chave_token_github_usuario3")
function help(){
echo -e "\nO ${0##*/} deve ser executado dentro da pasta do projeto somente uma unica vez\n"
echo -e "Usage: ${0##*/} [ -u \"user_git\" | --user ]\n\n[ -p \"project_name\" | --proj ]\n\n[ -c \"comemt alter project\" | --commit ]\n\n[ -h | --help]\n\n"
}
if [ $# -lt 3 ]; then
help
else
##Os : [obriga a digitar um argumento após a opção u,p,user,proj]
while getopt u:p:c:user:proj:coment:h,help option
do
case "${option}" in
-u|--user)
USER_GIT="${OPTARG}"
;;
-p|--proj)
PROJECT_NAME="${OPTARG}"
;;
-c|--coment)
COMENTARIO="${OPTARG}"
;;
-h|--help)
help
;;
--)
help
;;
*)
echo "Unexpected option: ${1}"
help
;;
esac
done
for ((i = 0; i < "${#USERS_GIT[@]}"; i++))
do
if [[ "${USERS_GIT[$i]}" == "${USER_GIT}" ]]; then
#Criando os repositprios remotamente sem logar no github
${CURL} -i -H "Authorization: token ${ACESS_TOKEN[$i]}" -d "{\"name\":\"${PROJECT_NAME}\",\"private\":false}" https://api.github.com/user/repos
if [[ "${PROJECT_NAME}" != "${PWD[@]/*\/}" ]]; then
mkdir ${PROJECT_NAME}
cd ${PROJECT_NAME}
#Inicializa o repositório
${GIT} init
##Cria um README no projeto
echo "## README ${PROJECT_NAME}" >> README.md
echo "### PROJETO criado com o script gitpratico" >> README.md
## Adiciona todos os arquivos existentes na pasta
${GIT} add .
#echo "Digite um comentário sobre o que você fez no projeto: "
#echo
#read -p "Entre com o comentario: " COMENTARIO
##Comitando o projeto
${GIT} commit -m "${COMENTARIO}"
#Modifica o branch atual criado pelo commit
${GIT} branch -M main
#Apos fazer qualquer alteração estas configurações permiten fazer apenas "git push" no projeto
#Sem precisar digitar toda vez: git push [email protected]:$USERS_GIT/${PROJECT_NAME}.git main
#Todos os repositórios criados com o script terão "branch master"
echo "[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote \"origin\"]
url = git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch \"main\"]
remote = origin
merge = refs/heads/main"> .git/config
echo "Copie e cole seu token caso nescessário ou digite a senha configurada na chave ssh do github"
echo
${GIT} push git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git main
elif [[ ${PROJECT_NAME} == ${PWD[@]/*\/} ]]; then
README="$(ls -1 README.md 2> /dev/null)"
#Inicializa o repositório
${GIT} init
if [ -z "${README}" ]; then
##Cria um README caso o projeto nao tenha nada na pasta ainda
echo "## README ${PROJECT_NAME}" >> README.md
echo "### PROJETO criado com o script gitpratico" >> README.md
else
echo "### PROJETO criado com o script gitpratico" >> README.md
fi
## Adiciona todos os arquivos existentes na pasta
${GIT} add .
#echo "Digite um comentário sobre o que você fez no projeto: "
#echo
#read -p "Entre com o comentario: " COMENTARIO
##Comitando o projeto
${GIT} commit -m "${COMENTARIO}"
#Modifica o branch atual criado pelo commit
${GIT} branch -M main
#Apos fazer qualquer alteração estas configurações permiten fazer apenas "git push" no projeto
#Sem precisar digitar toda vez: git push [email protected]:${USER_GIT}/${PROJECT_NAME}.git main
#Todos os repositórios criados com o script terão "branch master"
echo "[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote \"origin\"]
url = git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch \"main\"]
remote = origin
merge = refs/heads/main"> .git/config
echo "Copie e cole seu token caso nescessário ou digite a senha configurada na chave ssh do github"
echo
${GIT} push git@${HOSTS_GITHUB_USERS[${i}]}:${USERS_GIT[${i}]}/${PROJECT_NAME}.git main
fi #Fim PWD
fi #Fim USERS_GIT
done #Fim for
fi
スクリプトからこのエラーを削除しても、まだ無限に繰り返され、予期しないオプションが表示されます。 getoptsをgetoptに変更しました。
予期しないオプション:-uなど
答え1
(簡潔にするために、この回答は質問で尋ねるコードのオプション解析エラーに焦点を当てていますが、コードに存在する可能性がある他の問題は無視します。)
長いオプションをサポートしていないことに加えて、標準getopts
ユーティリティはオプション文字を配置します。いいえ与えられた変数のダッシュ。
これは、case
コマンドライン解析ループのステートメントをダッシュなしでtest u
、p
およびに変更する必要があることを意味します。この場合、エラーメッセージは不明なオプションとは関連がない可能性があるため、代わりに言及するように変更される可能性があります。また、これ以上の処理は不可能であるため、エラーメッセージの出力に従う必要があると考えられています。c
h
*
-$option
$1
exit 1
答え2
getopts
(sを含む)は標準ユーティリティであり、長いオプションをサポートしていないため、getopts c:p:u:user:proj:commit:h
手段などはc
argを取るオプションであり、whileなどは長いオプションをサポートしない(単一文字)オプションです。そこに文字を2回指定するとどうなるかわかりません。p
u
u
s
e
r
(sなしで)使用するにはgetopt
util-linuxまたはBusyboxの拡張バージョンが必要で、正しく使用するには注意が必要です。たとえば、参照してください。私の以前の答えはここにあります。(参考が一番見つけやすいので選んでいます。) 従来のgetopt
実装は空白などではうまくいかず、長いオプションもサポートしていません。
さらに、getopts
シェルで実装しても、位置パラメータ自体は変更されません。したがって、そのエラーを印刷すると、echo "Unexpected option: ${1}"
実際の最初の引数は常にスクリプトに印刷されます。これは問題のエラーとは無関係です。たとえば、ここでは常に次-a
から始めます$1
。
$ sh -c 'while getopts ab opt; do echo "$opt $1"; done' sh -a -b -c
a -a
b -a
Illegal option -c
? -a