O que acontece é que você literalmente pede ao shell para encontrar ~/test
do diretório em que o script está atualmente. Em outras palavras, se você executar a partir de /home/$USER
, ele estará procurando pelo arquivo test
no subdiretório ~
, não a expansão /home/$USER/test
.
O que você pode usar é o eval construído em bash
, que pegará todos os argumentos e os reunirá como um comando e deixará o shell executá-lo. Agora, o shell expandirá ~
.
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
Sugiro que você também use aspas em torno da substituição de comando $( . . .)
, para garantir que os arquivos com espaços neles e caracteres especiais sejam capturados adequadamente em file_to_copy
variable
ADIÇÃO
Como afirmado nos comentários, eval
integrado pode ser perigoso.
Pessoalmente, uso o comando readlink
com bastante frequência em meus scripts e evito usar ~
. E como neste script você solicita a entrada do usuário, por que não usar argumentos de linha de comando? Assim:
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 e basename
GNU coreutils fornece dois comandos, basename
e dirname
. basename
mostra o último elemento no caminho e dirname
mostra tudo que precede o último elemento. Pode-se usar a expansão de parâmetro interno de bash
para fazer o mesmo, mas já que temos essas ferramentas - por que não usá-las:
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;}