[SOLVED] Bash scripting: how to handle ampersand in a string for a positional parameter?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Bash scripting: how to handle ampersand in a string for a positional parameter?
Hello all!
I'm really stumped on this. I've been having fun in my .bashrc with shell functions, including making one for a command "pull." But I'm having a hard time figuring out how to handle strings that include "&". For instance:
~]$ pull file domain.tr/1em121cww
works no problem.
But
~]$ pull file domain.tr/1em121cww&s3fs12kfs
does not.
I know the easy solution is on the command line to simply write
~]$ pull file "domain.tr/1em121cww&s3fs12kfs"
but it's not so easy when you have multiple filenames (making use of positional parameter "${@:2}").
Is there some other way of handling the ampersand in the shell function? I thought maybe with sed, but this ampersand creates an issue before the shell function runs. I also don't want to process (escape, quote) every bash input with ampersands - just what I use for the "pull" command.
It's really a control operator issue. The issue I have is when I try to run the command on what is positional parameter and there is a character that is also a control operator - sorry if I wasn't clear on this in my first post. For instance:
~]$ dl song domain.tr/1em121cwws3fs12kfs
does work.
But
~]$ dl song domain.tr/1em121cww&s3fs12kfs
does not work.
In my .bashrc, I have this as part of a number of other lines:
Code:
dl() {
# First, we define the variables:
TorLaunch="/home/me/location1/tor-browser_en-US/Browser/start-tor-browser"
YtDL_base="youtube-dl --no-progress --console-title --ignore-errors --no-mtime"
YtDL_audio="-x --audio-format mp3 -f bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio -k --embed-subs"
if [[ $1 == "song" ]]; then
while true; do
read -p "(T)or download, (D)ownload, or (Q)ueue? : " tdq
case $tdq in
[Tt]* )
$TorLaunch &
until [ "$(proxychains4 curl -v --silent icanhazip.com 2>&1 | grep -i fail | wc -l)" -lt 1 ] || (( count++ >= 5 )) ;
do echo "Attempting to connect Tor..." && sleep 3;
done
proxychains4 -q $YtDL_base -o /home/me/location2/youtube-dl/'%(title)s'.flv $YtDL_audio "${@:2:99}"
break;;
[Dd]* )
$YtDL_base -o /home/me/location2/youtube-dl/'%(title)s'.flv $YtDL_audio "${@:2:99}"
break;;
...and so on and so forth...
That issue occurs before the "dl" script code runs - ampersand is a special character, you need to escape it or wrap the input in single-quotes to have Bash treat it as a literal.
Quote:
dl song 'domain.tr/1em121cww&s3fs12kfs'
(Unrelated to your issue, but instead of "${@:2:99}" you may prefer adding shift 1 after you've extracted the first argument, so you can then just use "$@" to get the rest.)
@OP Please use [code] tags not [quote] tags when inserting code.
You could only solve this if you used a special shell that doesn't support background jobs (so &ersand isn't special character) -- I don't know of such shell though.
(Unrelated to your issue, but instead of "${@:2:99}" you may prefer adding shift 1 after you've extracted the first argument, so you can then just use "$@" to get the rest.)
Assuming you wanted all but the first, obviously above is best suggestion, but the 99 is superfluous unless you are imagining 100s of parameters and you are limiting to less than 100??
Strange. "$@" should Do The Right Thing wrt double quotes - so I guess "${@:2:99}" should also do it.
- try the shift mentioned, then just "$@"
- try "$*" as well
and show us what it does.
Ok, thanks a lot for this feedback! I'll give those a try. I was avoiding shift because it destroys the positional parameter, and I thought I'd preserve them because I'm a saving kind of guy. I'll give it a shot and report back.
If you're dealing with web stuff like that then you might want to put an en/decoder for URL stuff there anyway.
In case you want an upload function at one point, or something, too.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.