Bash - Error parsing ~ in environment variable - bash

I have environment variable export MY_WORK_DIR="~/project".
While I'm using below command, it give me an error:
realpath $MY_WORK_DIR
realpath: '~/project': No such file or directory
In my guess, the ~ is not processed while using this env variable.
BTW, export MY_WORK_DIR=~/project is not an option for me. ~ should be in the string.
Could you please guide me how to get real path from envrionment variable ~/project ?
EDIT
Sorry. The variable is from other app so I cannot modify the environment variable which contains tilde. (Storing variable with tilde expanded form is not an option).
EDIT2
Is it safe to use eval command like this? eval "echo ${MY_WORK_DIR}". It works for my use.

I wouldn't use eval if I can avoid it. Especially in the way you are doing it, this is an invitation to do havoc by embedding dangerous code into MY_WORK_DIR.
A cheap solution for your concrete example would be to do a
if [[ ${MY_WORK_DIR:0:1} == '~' ]]
then
MY_WORK_DIR="$HOME/${MY_WORK_DIR:1}"
fi
which chops off the annoying ~ and prepends your home directory. But this would fail if MY_WORK_DIR is set to, say, ~einstein/project.
In this case, you would have to extract the user name (einstein) and search the home directory for this user.

Following steps can provide a resolution:
You need to replace "~" with the full path of the project directory.
Use pwd command to identify the full path of the project directory; e.g. /root/Documents/project is the full path you get.
Execute this command export MY_WORK_PROJECT=/root/Documents/project
Execute this command echo $MY_WORK_PROJECT so you should get this result
/root/Documents/project

Related

Why am I getting " No such file or directory" for a directory that exists?

I'm running a script called setenv.sh that sets the environment variables. One of the lines is:
config.dir=/Users/arianna/work/next/conf
After running it, I get an error message saying: config.dir=/Users/arianna/work/next/conf: No such file or directory
I'm confused because this directory exists. I can copy and paste and cd into it.
I'm befuddled here. What's wrong?
Using a . in your variable is what is causing problems; in bash it's used as an environment variable and/or only valid within certain shells which can recognize it as a regular variable. I would recommend using an underscore unless you absolutely need to use a dot.
config_dir=/Users/arianna/work/next/conf
If you want to use it as an environment variable or retrieve it then you could do:
config_dir=$( env 'config.dir=/Users/arianna/work/next/conf' \
awk 'BEGIN {print ENVIRON["config.dir"]}' )
echo "$config_dir"
Explanation:
↳ Reference to a bash variable whose name contains dot

Why does my PWD variable not retain its value?

I have the following code:
PWD="$(pwd)"
echo $PWD
cd
echo $PWD
If I run this from within /home/USER/sandbox, the output of the above is:
/home/USER/sandbox
/home/USER
Why does PWD not preserve its value? Is there any way to get it to preserve its value?
The key is that you called the variable PWD. This is one of several all-uppercase names used specially by Bash:
PWD
The current working directory as set by the cd command.
After each cd command, $PWD is updated to match.
I recommend you use lower-case for your variable names, to avoid surprises like this.
If I type all of those commands into the command line, I find that WD does "preserve it's value".
However I've run into this issue multiple times with various scripts and the root cause is one shell session (and/or a script) doesn't transfer its environment to another. Common solutions include doing everything I want to do in one script and saving values in a file for later use.
Hope this helps.

expr command not found? Why is expr not found but everything else is?

I have spent several hours trying to make the following piece of code work
PATH="C:\Ben\MyPictures"
echo $PATH
MY=`expr 2 + 2`
but this will not work because "expr: command not found". The only thing I've dug on StackOverflow are pathing issue (I.E. set my environment variable), but if that's the problem, why would other functions like echo, let, and declare already work fine?
For more context, this is on a near-fresh installation of window's cygwin. My question is why can't I find expr?
You have modified your PATH to have only 1 directory(therefore it cant find expr). You must append your new path to PATH and not replace existing PATH values, like this:
export PATH="$PATH:C:\Ben\MyPictures"
Also instead of calling an external process expr for calculation you can use the bash's builtin arithmetic evaluation:
$ echo $((2+2))
4
Edit:
Yes those would work because they are not executable files found from directories listed in $PATH.
Instead they(echo, type etc) are functionality provided by the bash shell itself called shell built-ins.
Type out type echo and type expr to know what type of command is it(alias/shell builtin/executable file etc.)
Shell built-ins help can be usually found out by help shellBuiltin where as we use man pages for executable files.
PS: type itself is a shell built-in(see type type)
The path variable PATH is used to find the location of standard binaries that ship with your environment. In fact system environment variables are usually capitalized( for example HOME ).
In your command :
PATH="C:\Ben\MyPictures"
You have accidentally(or intentionally?) replaced the standard paths to the standard binaries by C:\Ben\MyPictures so that command interpreter, bash here, can no longer find expr. When you use capitalized variables,say PATH, you could do:
if [ -z "$PATH" ] #check if a variable is empty
then
PATH="C:\Ben\MyPictures"
else
PATH="$PATH:C:\Ben\MyPictures"
fi
The better option indeed is to use small letters for user defined variables :
path="C:\Ben\MyPictures"
#in this case you should not get an error for expr but
# I am not sure how a Linux-Like environment handle character case.
# check that out.

shell script to copy files from one directory to another

Trying to write a simple script to copy some files in OS X 10.9.
Here's the content..
SRC_DIR="~/Library/Preferences-Old"
DST_DIR="~/Library/Preferences"
FILEN="test.txt"
cp $SRC_DIR/$FILEN $DST_DIR
Gives me the output:
cp: ~/Library/Preferences-Old/test.txt: No such file or directory
Of course, the above is wrong. The exact same cp command in terminal directly does the trick. What am I doing wrong here?
~ is one of the few exceptions to the rule "When in doubt, quote". As others have pointed out, a quoted ~ is not subject to expansion. However, you can still quote the rest of the string:
SRC_DIR=~"/Library/Preferences-Old"
DST_DIR=~"/Library/Preferences"
Note that depending on the values assigned to the two *_DIR variables, it's not enough to quote the values being assigned; you still need to quote their expansions.
FILEN="test.txt"
cp "$SRC_DIR/$FILEN" "$DST_DIR"
Your double-quotes are preventing the shell from converting your ~ into an actual path. Observe:
$ echo ~
/home/politank_z
$ echo "~"
~
~ isn't an actual location, it is shorthand for the path of your home directory.
As already mentioned double-quotes disabled ~ expansion.
Better approach is to use HOME variable:
SRC_DIR="$HOME/Library/Preferences-Old"
DST_DIR="$HOME/Library/Preferences"

Is it feasible to store a string which includes a space to the variable in bash?

I want to put my ~/Library/Application Support/ directory to a variable in my ~/.bash_profile` to make it easier to reference from within Terminal. I first attempted to define it as follows:
export L=~/Library/Application\ Support
However, when I tried to source ~/.bash_profile and then called ls $L, I got an error: /Users/username/Library/Application: Not a directory.
However, no matter how I define it I cannot define it properly, as far as I came up with the way to define it. Here's the list that I tried, but none of them worked properly.
~/Library/Application Support
"~/Library/Application Support"
"~/Library/Application\ Support"
So is it feasible to store a string which includes a whitespace to a variable in bash to begin with?
Your export statement is fine; the space is properly escaped. You just need to quote the expansion of the parameter, so that bash gives a single argument to the ls command:
ls "$L"

Resources