Using a variable to change directory - shell

I would like to extract the current path in a variable and use it later on in the script
Something like:
mypath="$pwd"
Later on:
cd "$mypath"
But I am getting a different directory when doing ls

Almost:
mypath=$PWD
This one saves a fork over mypath=$(pwd). While some consider it good practice to always double quote variable assignments, technically it is not needed here, since the shell does not perform word-splitting for variable assignments.
PS: Note that you are assigning to mypath and then use myvar... you should be consistent in your variable naming, otherwise it won't work.

Related

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.

Difference between ${my_variable} and $my_variable in a Jenkins project

Is there a difference when using variables in a Jenkins project between this:
node index.js ${arg}
and this:
node index.js $arg
Where arg is a parameter for the project.
Update:
Interesting to note that it's not Jenkins-specific.
I think this question should remain as others may assume it's something to do with Jenkins.
In the context of your Jenkins project, it is not needed, except as a matter of style.
The braces are useful in those cases where the shell may not be able to determine the end of a variable name. For instance, if your variable is named this, then you would need the braces if your command was
echo "${this}isatest"
Also, you need them when you want to take advantage of Bash's Shell Parameter Expansions.
It's actually a standard shell syntax.
It's easier to manipulate variables / concatenate the contents of variables into other variable names. e.g.
${foo}bar
You can also perform additional string manipulation with the {}:
STRING="This is a string"
echo ${STRING// /_}
http://www.tldp.org/LDP/abs/html/string-manipulation.html
I also find variables with {} to read better but that's a personal preference.
Generic answer here: When do we need curly braces in variables using Bash?

Bash:script cannot be called after adding the path

I am writing my own unix scripts so I want to add a new directory for Bash. I add sth in .bash_profile like this.
PATH="~/Documents:${PATH}"
export PATH
and in my ~/Documents, there is a file named test of which the content is
#!/usr/bin/env python3.5
print("hahahhah")
I also used
chmod 755 test
to make it executable.
But I cannot call it in terminal directly. ./test works as usual.
What went wrong?
After I change to
PATH="$HOME/Documents:${PATH}"
export PATH
nothing happens.
FDSM_lhn#9-53:~/Documents$ test
FDSM_lhn#9-53:~/Documents$ ./test
hahahhah
Solution:
The fundamental reason is that I have a command of the same name as default one, So it won't work any way! Changing name will be sufficient!
Tilde doesn't get expanded inside strings. So by quoting the right-hand side of the assignment you prevent it from being expanded and get a literal ~ in your PATH variable which doesn't help you any.
You have two ways to fix this:
Drop the quotes on the assignment (yes this is safe, even for $PATH values with spaces, etc.).
Use $HOME instead of ~.
I prefer the second solution but the first is entirely valid for this case.
Beware though that in places where you aren't doing a straight assignment you often cannot just drop the quotes and trying to use ~ will cause problems.
In which case you will end up finding a question like this with an answer like this and something ugly like this.

How to pass multiple variables in shell script

I have a shell script that I'm trying to write to a file using multiple variables, but one of them is being ignored.
#!/bin/bash
dir=/folder
name=bob
date=`date +%Y`
command > $dir/$name_$date.ext
The $name is being ignored. How can I fix this?
Have you noticed that the _ was "ignored" as well? That's a big hint.
If you use set -u, you'll see the following:
-bash: name_: unbound variable
The way bash parses it, the underscore is part of the variable name.
There are several ways to fix the problem.
The cleanest is the ${var} construct which separate the variable name from its surroundings.
You can also use quotation in various ways to force the right parsing, e.g.: "$dir/$name""_$date.ext"
And in case your variables might contain spaces (now, or in the future) use quotation for words.
command >"$dir/${name}_$date.ext"
command >"${dir}/${name}_${date}.ext"
Both these are fine, just pick one style and stick to it.

How to open files relative to home directory

The following fails with Errno::ENOENT: No such file or directory, even if the file exists:
open('~/some_file')
However, I can do this:
open(File.expand_path('~/some_file'))
I have two questions:
Why doesn't open process the tilde as pointing to the home directory?
Is there a slicker way than File.expand_path?
Not sure if this was available before Ruby 1.9.3 but I find that the most elegant solution is to use Dir.home which is part of core.
open("#{Dir.home}/some_file")
The shell (bash, zsh, etc) is responsible for wildcard expansion, so in your first example there's no shell, hence no expansion. Using the tilde to point to $HOME is a mere convention; indeed, if you look at the documentation for File.expand_path, it correctly interprets the tilde, but it's a feature of the function itself, not something inherent to the underlying system; also, File.expand_path requires the $HOME environment variable to be correctly set. Which bring us to the possible alternative...
Try this:
open(ENV['HOME']+'/some_file')
I hope it's slick enough. I personally think using an environment variable is semantically clearer than using expand_path.
Instead of relying on the $HOME environment variable being set correctly, which could be a hassle when you use shared network computers for development, you could get this from Ruby using:
require 'etc'
open ("#{Etc.getpwuid.dir}/some_file")
I believe this identifies the current logged-in user and gets their home directory rather than relying on the global $HOME environment variable being set. This is an alternative solution to the above I reckon.
I discovered the tilde problem, and a patch was created to add absolute_path
which treats tilde as an ordinary character.
From the File documentation:
absolute_path(file_name [, dir_string] ) → abs_file_name
Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point. If the given pathname starts with a “~” it is NOT expanded, it is treated as a normal directory name.

Resources