View previous topic :: View next topic |
Author |
Message |
guyuming Apprentice
Joined: 19 Nov 2020 Posts: 253
|
Posted: Fri Jan 10, 2025 7:40 am Post subject: how to read in user input ~/Downloads and resolve the ~? |
|
|
I need to read user input file path such as ~/Download with readline history, and resolve it with realpath.
however, the file_path variable value seems to have single quotation mark around it, so realpath says file not found in Chinese.
but if i echo $file_path, no single quotation mark shown.
How can I resolve user input from ~/Downloads into /home/guyuming/Downloads then?
Code: | guyuming@localhost ~ $ read -e -r file_path
~/Downloads
guyuming@localhost ~ $ realpath $file_path
realpath: '~/Downloads': 没有那个文件或目录
guyuming@localhost ~ $ echo $file_path
~/Downloads
guyuming@localhost ~ $ realpath '~/Downloads'
realpath: '~/Downloads': 没有那个文件或目录
guyuming@localhost ~ $ realpath ~/Downloads
/home/guyuming/Downloads
guyuming@localhost ~ $ |
|
|
Back to top |
|
|
grknight Retired Dev
Joined: 20 Feb 2015 Posts: 1978
|
Posted: Fri Jan 10, 2025 2:03 pm Post subject: |
|
|
The reason why the last manual attempt works is because the shell expands the ~ before realpath sees it. The variable never is single quoted.
A way around this is to expand any leading ~ to $HOME after the read: Code: | file_path="${file_path/#~/${HOME}}" |
This may not work in all shells, but it definitely works in bash. |
|
Back to top |
|
|
guyuming Apprentice
Joined: 19 Nov 2020 Posts: 253
|
Posted: Fri Jan 10, 2025 2:21 pm Post subject: |
|
|
grknight wrote: | The reason why the last manual attempt works is because the shell expands the ~ before realpath sees it. The variable never is single quoted.
A way around this is to expand any leading ~ to $HOME after the read: Code: | file_path="${file_path/#~/${HOME}}" |
This may not work in all shells, but it definitely works in bash. |
Thank you very much! I had scratched my head on this for one day. |
|
Back to top |
|
|
flexibeast Guru
Joined: 04 Apr 2022 Posts: 479 Location: Naarm/Melbourne, Australia
|
Posted: Sat Jan 11, 2025 12:16 am Post subject: |
|
|
grknight wrote: | This may not work in all shells |
Yeah, unfortunately this very handy syntax isn't POSIX, so although it works in Bash, Zsh and OpenBSD Ksh, it won't work in Dash. So a more generic solution is to use prefix pattern removal:
Code: | $ file_path='~/Downloads'
$ echo "${HOME}${file_path#\~}" |
_________________ https://wiki.gentoo.org/wiki/User:Flexibeast |
|
Back to top |
|
|
guyuming Apprentice
Joined: 19 Nov 2020 Posts: 253
|
Posted: Sat Jan 11, 2025 1:05 am Post subject: |
|
|
i think both "${HOME}${file_path#\~}" and "${file_path/#~/${HOME}}" are like those four-words-Chinese-idioms: concise, but nightmare for many kids
I had long taken for granted that realpath command will translate ~ for me. Literally, you see, realpath, means it, doesn't it?
so, i would suggest to enhance the realpath command with a option, such as --home for this. |
|
Back to top |
|
|
flexibeast Guru
Joined: 04 Apr 2022 Posts: 479 Location: Naarm/Melbourne, Australia
|
|
Back to top |
|
|
Goverp Advocate
Joined: 07 Mar 2007 Posts: 2196
|
Posted: Sat Jan 11, 2025 10:49 am Post subject: |
|
|
There's an interesting discussion of handling this issue in Stackoverflow _________________ Greybeard |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 22973
|
Posted: Sat Jan 11, 2025 4:00 pm Post subject: |
|
|
Assuming use of bash with readline support enabled, it looks from my limited testing like compgen -W does what is needed: Code: | $ v='~root'
$ compgen -W "$v"
/root
$ v='~dhcpcd'
$ compgen -W "$v"
/var/chroot/dhcpcd
| Why is use of realpath a requirement? |
|
Back to top |
|
|
|