Проверьте, что Shell Script $1 является абсолютным или относительным путем
Как говорится в названии, я пытаюсь определить, получает ли мой bash script полный путь или относительный файл в каталог как параметр.
По некоторым причинам для меня не работает следующее:
#!/bin/bash
DIR=$1
if [ "$DIR" = /* ]
then
echo "absolute"
else
echo "relative"
fi
Когда я запускаю свой script с полным путем или абсолютным путем, он говорит:
./script.sh: line 5: [: too many arguments
relative
По некоторым причинам я не могу понять эту ошибку. Любые идеи?
Ответы
Ответ 1
[ ... ]
не соответствует шаблону. /*
расширяется до содержимого /
, поэтому у вас есть
if [ "$DIR" = /bin /boot /dev /etc /home /lib /media ... /usr /var ]
или что-то подобное. Вместо этого используйте [[ ... ]]
.
if [[ "$DIR" = /* ]]; then
Ответ 2
Просто проверьте первый символ:
if [ "${DIR:0:1}" = "/" ]
Ответ 3
ShellCheck автоматически указывает, что "[ .. ] can't match globs. Use [[ .. ]] or grep.
"
Другими словами, используйте
if [[ "$DIR" = /* ]]
Это связано с тем, что [
является регулярной командой, поэтому /*
предварительно расшифровывается оболочкой, превращая ее в
[ "$DIR" = /bin /dev /etc /home .. ]
[[
обрабатывается специально оболочкой и не имеет этой проблемы.
Ответ 4
Письменные тесты - это весело:
#!/bin/bash
declare -a MY_ARRAY # declare an indexed array variable
MY_ARRAY[0]="/a/b"
MY_ARRAY[1]="a/b"
MY_ARRAY[2]="/a a/b"
MY_ARRAY[3]="a a/b"
MY_ARRAY[4]="/*"
# Note that
# 1) quotes around MY_PATH in the [[ ]] test are not needed
# 2) the expanded array expression "${MY_ARRAY[@]}" does need the quotes
# otherwise paths containing spaces will fall apart into separate elements.
# Nasty, nasty syntax.
echo "Test with == /* (correct, regular expression match according to the Pattern Matching section of the bash man page)"
for MY_PATH in "${MY_ARRAY[@]}"; do
# This works
if [[ $MY_PATH == /* ]]; then
echo "'$MY_PATH' is absolute"
else
echo "'$MY_PATH' is relative"
fi
done
echo "Test with == \"/*\" (wrong, becomes string comparison)"
for MY_PATH in "${MY_ARRAY[@]}"; do
# This does not work at all; comparison with the string "/*" occurs!
if [[ $MY_PATH == "/*" ]]; then
echo "'$MY_PATH' is absolute"
else
echo "'$MY_PATH' is relative"
fi
done
echo "Test with = /* (also correct, same as ==)"
for MY_PATH in "${MY_ARRAY[@]}"; do
if [[ $MY_PATH = /* ]]; then
echo "'$MY_PATH' is absolute"
else
echo "'$MY_PATH' is relative"
fi
done
echo "Test with =~ /.* (pattern matching according to the regex(7) page)"
# Again, do not quote the regex; '^/' would do too
for MY_PATH in "${MY_ARRAY[@]}"; do
if [[ $MY_PATH =~ ^/[:print:]* ]]; then
echo "'$MY_PATH' is absolute"
else
echo "'$MY_PATH' is relative"
fi
done
Ответ 5
Еще один случай - это путь, начинающийся с ~
(тильда). ~user/some.file
или ~/some.file
- это какие-то абсолютные пути.
if [[ "${dir:0:1}" == / || "${dir:0:2}" == ~[/a-z] ]]
then
echo "Absolute"
else
echo "Relative"
fi