J'ai cherché sur internet mais n'ai pas trouvé de réponse complètement satisfaisante.

Supposons qu'une variable contienne le nom d'un répertoire ou d'un fichier, commençant par ~, par exemple, parce que c'est plus sympa à afficher.
Y a-t-il moyen de demander au shell l'expansion a posteriori du tilde?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dir="~/TMP"
echo "Votre dir est '$DIR'"
=> Votre dir est '~/TMP'   # ok. c'est ce que je veux
 
echo "Votre dir '$DIR' contient:"
=> Votre dir '~/TMP' contient:   # ok. c'est toujours ce que je veux
 
ls $DIR
=> ls: ~/TMP: No such file or directory # Pourtant ~/TMP existe... ou, au moins, $HOME/TMP
 
cd $DIR
=> -bash: cd: ~/TMP: No such file or directory
 
for f in $somedir/* ; do echo $f; done
=> ~jack/TMP/*   # Bof... je préfèrerais la liste des fichiers de $HOME/TMP
J'ai trouvé des solutions partielles, comme:
mais elle utilise eval (qui est dangereux... bon, a priori, je sais ce que j'ai mis dans "$dir"...)

Et elle ne marche pas bien s'il y a des espaces:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
dir="~/dir with spaces"
eval cd "$dir"
=> -bash: cd: /Users/jack/dir: No such file or directory
Autre proposition, remplacer "~" par "$HOME", mais ça ne marche pas pour un autre home:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
dir="~jack/TMP";
cd ${dir/#\~/$HOME}
=> -bash: cd: /Users/jackjack/TMP: No such file or directory
 
cd $(echo $dir | sed "s#^~#$HOME#")
=> -bash: cd: /Users/jackjack/TMP: No such file or directory
J'ai bien réussi à bidouiller la première avec:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
dir="~jack/dir with spaces"
eval "ls -ld $(echo "$dir" | sed -e 's|/\(.*\)|/"\1"|')"
drwxrwxr-x  2 jack  staff  68 17 déc  2014 /Users/jack/dir with spaces/
mais j'ai encore un appel à eval...

Voyez-vous des bugs dans cette dernière solution?
Connaissez-vous un moyen de faire sans eval?