Вопрос или проблема
Команда cp завершается неудачей, когда путь к файлу хранится в переменной с использованием относительного пути.
Рассмотрим файл в домашнем каталоге ~/test.txt
и переменные my_file1=~/test.txt
и my_file2=/home/user/test.txt
.
Тогда команда cp завершается с ошибкой:
cp ${my_file1} ./
. Но она работает с абсолютным путем cp ${my_file2} ./
или с относительным путем, не хранящимся в переменной cp ~/test.txt ./
У кого-нибудь есть идея, что здесь происходит?
Я попробовал добавить кавычки вокруг переменной.
Ответ или решение
Проблема, с которой вы столкнулись при использовании команды cp
с относительными путями, связана с тем, как оболочка обрабатывает символ ~
, который обозначает домашний каталог пользователя.
Когда вы задаете переменную my_file1
со значением ~/test.txt
, оболочка не интерпретирует символ ~
в переменной. Это означает, что переменная my_file1
будет хранить строку ~/test.txt
как есть, а не как путь к файлу в вашем домашнем каталоге. Поэтому, когда вы используете cp ${my_file1} ./
, команда пытается скопировать файл с именем ~/test.txt
, находящийся в текущем каталоге, что вызывает ошибку, если файл там не существует.
Напротив, при объявлении переменной my_file2
как /home/user/test.txt
, вы указываете абсолютный путь, который интерпретируется правильно, поэтому команда cp ${my_file2} ./
работает без проблем.
Чтобы исправить вашу первую команду, вы можете использовать команду eval
или же просто разыменовать путь вручную. Вот несколько вариантов решения:
-
Прямое использование
eval
:my_file1=~/test.txt eval cp $my_file1 ./
-
Разыменование пути вручную:
my_file1=~/test.txt cp "$(eval echo $my_file1)" ./
-
Использование
realpath
(если доступно):my_file1=~/test.txt cp "$(realpath $my_file1)" ./
-
Простое указание пути в переменной:
Если вы хотите сразу избавиться от проблем с
~
, вы можете просто задать переменные с использованием полного пути:my_file1="/home/user/test.txt" cp ${my_file1} ./
Таким образом, ваша проблема решится, и команда cp
будет работать корректно. Не забудьте, что точные пути зависят от вашего настроенного окружения и пользователя, так что при задавании путей важно учитывать это.