Problem with неудар в лунку from простой рукописный шрифт that скопируй в file to в different directory

Эксперт someone trying to learn bash, I have been making простой scripts to тест out various commands. Простой In the following рукописный шрифт, I am experimenting with the read command.

#!/bin/bash
read -p "Enter a path to a file: " file_to_copy
cp $file_to_copy /tmp

If the user enters the entire path to в тест file e.g. / home / $USER/test when prompted, the рукописный шрифт executes эксперт expected and makes в copy of "тест" in the/tmp directory. However, if the user enters the shorthand ~/test, терминал returns the ошибка cp: cannot stat '~/test': Не such file or directory. Why is the command cp unable to find an equivalent representation of the file path when entered?

If I independently enter in терминал:

cp ~/test /tmp

the тест file is copied without incident, so it is probably в nuance of переменная assignment that I messed up, but I cannot фигурировал it out.

Thanks.

4
задан 21 December 2015 в 07:20

2 ответа

То, что происходит, - то, что Вы буквально просите окружать для нахождения ~/test из каталога сценарий в настоящее время находится в. Другими словами, если Вы работаете от /home/$USER, это будет искать файл test в названном подкаталоге ~, не расширение /home/$USER/test.

То, что можно использовать, bashоценка встроила, который возьмет любые аргументы и соединит их как одну команду и позволит оболочке выполнить ее. Теперь, оболочка расширится ~.

xieerqi:
$ ./copyScript.sh                                                                                                       
Enter a path to a file: ~/test
Entered /home/xieerqi/test

xieerqi:
$ ls -l /tmp/test
-rw-rw-r-- 1 xieerqi xieerqi 0 Dec 21 01:14 /tmp/test

xieerqi:
$ cat copyScript.sh
#!/bin/bash

read -p "Enter a path to a file: " file_to_copy
file_to_copy=$(eval echo $file_to_copy)
echo "Entered $file_to_copy"
cp "$file_to_copy" /tmp

Я предложил бы, чтобы Вы также использовали кавычки вокруг замены команды $( . . .) , гарантировать, что файлы с пробелами в них и специальном символе будут правильно получены в file_to_copy переменная

ДОПОЛНЕНИЕ

Как указано в комментариях, eval встроенный может быть опасным.

Лично, я использую readlink управляйте довольно часто в моих сценариях и избегайте использования ~. И с тех пор в этом сценарии Вы просите ввод данных пользователем так или иначе, почему бы не использовать параметры командной строки? Как так:

xieerqi:
$ ./copyScript.sh testFile.txt                                
/home/xieerqi/testFile.txt

xieerqi:
$ cat copyScript.sh                                           
#!/bin/bash

FILE="$(readlink -f "$@" )"

echo $FILE
# uncomment for copying
# cp $FILE /tmp

dirname и базовое имя

GNU coreutils обеспечивает две команды, basename и dirname. basename шоу длятся элемент в пути, и dirname шоу все предшествующее последнему элементу. Можно было использовать bashвнутреннее расширение параметра, чтобы сделать то же, но так как у нас есть эти инструменты - почему бы не использовать их:

xieerqi:
$ ./copyScript.sh                                             
Enter path to file: ~/testFile.txt
File entered is  /home/xieerqi/testFile.txt

xieerqi:
$ ./copyScript.sh                                             
Enter path to file: ~/sumFile.txt
File entered is  /home/xieerqi/sumFile.txt
ERROR, file doesn't exist

xieerqi:
$ cat copyScript.sh                                           
#!/bin/bash

read -p "Enter path to file: " FILEPATH

DIRPATH="$(dirname "$FILEPATH")"
FILENAME="$(basename "$FILEPATH" )"

if [ "$DIRPATH" == "~"   ];then
  DIRPATH="$HOME"
fi

FILEPATH="$DIRPATH"/"$FILENAME"
echo "File entered is " "$FILEPATH"

[ -e "$FILEPATH"  ] || { echo "ERROR, file doesn't exist"; exit 1;}
2
ответ дан 1 December 2019 в 09:22

Попробуйте эти команды в своем сценарии:

#!/bin/bash
read -p "Enter a path to a file: " file_to_copy
file_to_copy=$(bash -c "echo $file_to_copy")
file_to_copy=${file_to_copy/~\//$HOME\/}
cp "${file_to_copy}" /tmp

Объяснение:

  • третья строка расширится env значения переменных если любой подарок.

  • четвертая строка в вышеупомянутом коде попытается искать ~ в Вашем file_to_copy переменная, и, если найдено это будет замена $HOME путь.

  • И \/ здесь \ символ escape-последовательности обратной косой черты для /, поскольку мы хотим заменить ~/ $HOME/.

4
ответ дан 1 December 2019 в 09:22

Другие вопросы по тегам:

Похожие вопросы: