У меня в домашнем каталоге есть папка и файл со следующей структурой: ~/folder/file
.
У меня и папка, и файл получили полные права доступа (папка — 700, файл — 600). Следующая тестовая команда (она находится внутри скрипта оболочки, если это имеет значение) неожиданно (на мой взгляд) возвращает false.
[ -r ~/folder/file ]
echo $? #Prints 1->Failure
Однако если я использую альтернативный путь к файлу, например
pwd #Prints /home/myname
[ -r /home/myname/folder/file ]
[ -r folder/file ]
echo $? #Prints 0->Success
Я что-то пропустил?
test -r
возвращает true, если FILE
существует и разрешение на чтение предоставлено в соответствии с
man test
.
решение1
В конце концов, я нашел свою проблему. Дело в том, что я считывал путь с клавиатуры (команда чтения), и почему-то тильда (~) не расширялась. Решение этой проблемы было следующим:
echo 'Give path:'
read var1
var2=$(eval echo "$var1");
Теперь var2 содержит полный путь (раскрывая ~), и после этого я могу нормально использовать свои тесты.
решение2
В дополнениеОтвет Алатора, Необходимо отметить, чтоРасширение Тильдыпроводится только в следующих случаях:
- Присвоение переменной, без кавычек,
~
сразу после:
, как вmypath=~/Documents:~/usr/share/stuff
- Присвоение переменной после первой
=
,~
без кавычек, как вfoo=~/bar
- Начало «слова»:
~/ascript.sh
- Отдельное «слово»:
stat ~/afile.txt
read
берет буквальную последовательность символов stdin
и не выполняет расширение тильды; что еще важнее, расширение тильды выполняется самой оболочкой, а не ее отдельными встроенными командами.
Одним из способов решения этой проблемы может быть способ, eval
показанный Алатором, или использование подстановки параметров (что технически является просто ручным способом сделать то же самое):
~$ echo "${foo/\~/$HOME}"
/home/username/Documents
В качестве альтернативы, если вы не против запустить другой процесс (или вам приходится иметь дело с этими конкретными языками), вы можете использовать Python и Perl следующим образом:
python -c 'import sys,os; print os.path.expanduser(sys.argv[1])' "$foo"
perl -e 'print glob qq("$ARGV[0]")' "$foo" "$foo"