This question already has answers here:
tilde expansion in environment variable
(2 answers)
Closed 8 years ago.
I have the following script
file=${file:-letsdump.sh}
checkfile="~/mysql_backup/$file"
if [ -e "$checkfile" ]; then
mv ~/mysql_backup/$file ~/mysql_backup/$file-bak-$(date +%d%m%Y_%H%M).bak
else
echo 'file doesnt exist'
fi
I know my file is there, I am thinking it could be something to do with the ~/ ?
It never finds the file
Double quotes (really, any quotes) prevent ~ from being expanded. Use instead:
checkfile=~/mysql_backup/"$file"
...or, even better, use $HOME in all scripts, and consider ~ to be a facility for interactive/human use only.
The ~ character is not expanded inside double-quoted strings.
In this context, ~ is equivalent to $HOME, which is expanded in double-quoted strings, so you could write:
checkfile="$HOME/mysql_backup/$file"
When followed by a user name, ~ refers to that user's home directory, which is not tracked by any environment variable; "~fred/" would not expand, but writing something that does expand correctly in that context is more difficult. You can leave it outside the quotes, but that could cause problems if the home directory path includes a space -- which I hope would never actually happen. Correction, thanks to Charles Duffy: String splitting is disabled on assignments, so that wouldn't be an issue.
Related
This question already has answers here:
How do I create an alias where the arguments go in the middle? [duplicate]
(6 answers)
Closed 1 year ago.
I'm trying to do something like this. But it's not working.
$ alias setroot="export ROOT=$1; export PATH=$ROOT/bin:$PATH"
$ setroot /path/to/root
bash: export: `/path/to/root': not a valid identifier
Can someone point out, what is going wrong here?
To clarify, I need ROOT also in my environment.
Alias is literally replaced and $1 is empty, because your interactive shell was started with no arguments and all variables $1, $ROOT and $PATH are expanded when defining your alias, because you used double quotes. So:
setroot /path/to/root
does:
export ROOT=; export PATH=<content_of_ROOT>/bin:<content_of_PATH> /path/to/root
The second argument to second export is invalid identifier - /path/to/root contains /, and variables can't contain /. The content_of_ROOT is the value of ROOT when defining alias, not upon using it.
Use a function. Check your scripts with shellcheck.
This question already has answers here:
How to store curly brackets in a Bash variable
(2 answers)
Closed 4 years ago.
I'm trying to use this variable
MediaExt="*.{mp4,mkv,avi}"
in this command
mv ${MediaSource}/${MediaExt} ${UploadDir}
but it doesn't seem to work.
Could someone help me, please? Thanks!
A command in bash is parsed in several passes. The pass that decides whether globbing (expanding *, or *.{mp4,mkv,avi}) should be performed, is occurring before the pass that expands the variables. Once the variables are expanded, there are candidate for globbing, but the decision that no globbing is required has already been made
It will work if you write the expression as:
mv ${MediaSource}/*.{mp4,mkv,avi} ${UploadDir}
You'll probably find some advise that you can use eval. Please don't!
This:
eval mv ${MediaSource}/${MediaExt} ${UploadDir}
will execute as you intended, but eval can be dangerous if you don't control the values of the variables. For example, if UploadDir could be set to:
UploadDir="somedirectory; rm -rf ~"
then eval will execute your request as two statements and remove all your files.
This question already has answers here:
Brace expansion with variable? [duplicate]
(6 answers)
Closed 5 years ago.
How do I expand a brace expansion that originally come from a string variables ? Note that the string variable is a requirement.
#!/usr/bin/env bash
TEXT_DIRS='opt/*/{doc,gtk-doc}'
My intention is reading a bash source from zsh, or maybe other language as well such as Perl or Python. Get the configuration from /etc/makepkg.conf, as below.
DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc})
It is all, for just, learning purpose.
Is that possible, to expand from string ?
The tricky thing here is that once Bash resolves the environment variable, it doesn't make another pass to process its contents again. You'd have to evaluate the content of the variable in another pass of the shell ( eg another shell command).
Here's one way to do that:
bash-4.4# TEXT_DIRS='/usr/*/{bin,src,lib}'
bash-4.4# bash -c ls\ $TEXT_DIRS
ls: /usr/*/src: No such file or directory
/usr/local/bin:
/usr/local/lib:
Here, I'm dynamically generating a shell command that I then evaluate to handle the 2nd expansion. (I took the liberty of changing the paths to something that would match on typical systems, so make sure to change it back if you try to test).
Dynamically generating code is always dangerous, if you can't trust the input. That's essentially how command injection attacks work. But use of eval in your own shell with trusted input is more or less "safe", though I rarely find myself using it unless in a contrived scenario like yours, or some of my own worse ideas.
This question already has answers here:
Echoing a tilde to a file without expanding it in Bash
(3 answers)
Pass a special variable (~ tilde) to Java program
(1 answer)
Closed 5 years ago.
I have a simple bash script that can accept arguments that it will be treating as text strings, nothing more.
If I give it ~, without quotes, then the home directory /home/users/me is what's parsed. Quote it, "~", it's fine. The character "~" is what I want, not the home path.
Is there any way I can ensure an un-quoted ~ is treated exactly as the character "~", not the home directory alias?
The bash shell is expanding the ~ on the command line before the argument is passed to your script.
There might be a bash option that you can change in your shell, but that would affect everything in your shell, which doesn't sound like what you want.
The short answer I think is no. There's nothing you can do in your script to change how the parent shell expanded any arguments before passing them to your script.
This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 6 years ago.
Usually when you use cURL the output looks like that:
alex$ curl http://some-url
some-content
But, for some urls the outputs is different:
alex$ curl http://some-url
[1] 81030
alex$ some-content
[1]+ Done curl http://some-url
Why is that happening and how to get rid of it and make cURL to output just the content?
Kevin's answer is helpful and Kevin deserves credit for inferring your specific problem in the absence of specific information.
Let me complement it with general recommendations:
Rather than individually escaping shell metacharacters (characters with special meaning to the shell) by \-prefixing them, consider:
enclosing literals in single quotes; e.g.: curl 'http://example.org/search&query=foo'
enclosing variable references in double quotes; e.g.: url='http://example.org/search&query=foo'; curl "$url"
That way you needn't worry about what individual characters to escape.
Generally, only use unquoted literals / variable references if you explicitly want the the shell to interpret them (by applying so-called shell expansions).
if some-url contains & character then shell interprets it as command to run the process in background.
To overcome it one can escape & with \& (prepend backslash).