How can I enter the directory with prefix '-t' - linux

By mistake, I create a directory with the prefix '-t' on a Linux server. For example, -train-20200514-081411. When I want to cd -train-20200514-081411, there is an error:
-bash: cd: -t: invalid option
cd: usage: cd [-L|-P] [dir]
So in this case, how can I use this directory?
Thank you very much for any help!

You can use:
cd -- -train-20200514-081411
The -- tells bash not to interpret any more items as flags, example transcript below:
[~]: mkdir -- -turkey; ls
-turkey other_file.txt
[~]: cd -- -turkey
[~/-turkey]: cd ..
[~]: rmdir -- -turkey; ls
other_file.txt

Related

Is this possible in this command to cd into the directory thats printed in output

When I do ls | grep -e *-folder1 it prints my-folder1 that's the name of the folder matched in the command in current directory.
Is there a way I can add something like cd into this directory. This is more of an attempt to learn Bash or commands on Linux, rather than about doing what I am trying to accomplish.
You could do
ls | grep -- -folder1 | while read -r dir
do
cd "$dir"
# do things in $dir
done
# do things in the original directory
but parsing the output of ls is not recommended. You could instead use globbing:
for dir in *-efolder*
do
cd "$dir"
# do things in $dir
cd .. # need to back out again
done
# do things in the original directory
If the purpose isn't to grep on all folders matching a certain pattern and to cd down into each one of them, but to simply cd into a directory ending with -folder1, then:
cd *-folder1
If you get zero or multiple hits, cd will shown an error.

mkdir create directory in current users directory - bash

#!/bin/bash
mkdir -p user_records
I want to create a directory user_records in the current user's directory. How do I achieve this? I tried adding sudo in front of mkdir but that does not create the directory in the desired location.
You should be able to access the user directory with ~, so you could try:
mkdir -p ~/user_records
Using the -p option is not necessary here. It is only useful if you want to create a hierarchy of directories. Example: if you want to create a "baz" directory inside a "bar" directory, inside a "foo" directory, inside the current directory, you will use the following command: mkdir -p foo/bar/baz.
In your Bash script, you have 3 simple solutions:
cd
#!/bin/bash
cd
mkdir user_records
~
#!/bin/bash
mkdir ~/user_records
$HOME
#!/bin/bash
mkdir "$HOME/user_records"

Does $PWD always equal $(realpath .)

Given
A modern Linux/UNIX/OSX (w/ realpath)
bash 4+ (even on OSX)
Is
"$PWD" == "$(realpath .)"
Always true?
It's pretty easy to test that this is not always the case.
$ mkdir /tmp/realdir
$ cd /tmp/realdir
$ echo $PWD
/tmp/realdir
$ ln -s realdir /tmp/fakedir
$ cd /tmp/fakedir
$ echo $PWD
/tmp/fakedir
$ realpath .
/tmp/realdir
so no, $PWD is not always the same as $(realpath .).
The bash manual indicates that the PWD variable is set by the built-in cd command. the default behaviour of cd is:
symbolic links are followed by default or with the -L option
This means that if you cd into a symlink the variable gets resolved relative to the symlink, not relative to the physical path. You can change this behavior for a cd command by using the -P option. This will cause it to report the physical directory in the PWD variable:
$ cd -P /tmp/fakedir
$ echo $PWD
/tmp/realdir
You can change the default behavior of bash using the -P option:
$ set -P
$ cd /tmp/fakedir
$ echo $PWD
/tmp/realdir
$ set +P
$ cd /tmp/fakedir
$ echo $PWD
/tmp/fakedir
This is of course notwithstanding the fact that you can assign anything you want to the PWD variable after performing a cd and it takes that value:
$ cd /tmp/fakedir
$ PWD=/i/love/cake
$ echo $PWD
/i/love/cake
but that's not really what you were asking.
It is not necessarily the case even when symbolic links are not used and PWD is not set by the user:
vinc17#xvii:~$ mkdir my_dir
vinc17#xvii:~$ cd my_dir
vinc17#xvii:~/my_dir$ rmdir ../my_dir
vinc17#xvii:~/my_dir$ echo $PWD
/home/vinc17/my_dir
vinc17#xvii:~/my_dir$ realpath .
.: No such file or directory
Note that under zsh, ${${:-.}:A} still gives the same answer as $PWD (the zshexpn(1) man page says about the A modifier: "Note that the transformation takes place even if the file or any intervening directories do not exist.").
Note that however, $PWD contains obsolete information. Using it may be a bad idea if some other process can remove the directory. Consider the following script:
rm -rf my_dir
mkdir my_dir
cd my_dir
echo 1 > file
cat $PWD/file
rm -r ../my_dir
mkdir ../my_dir
echo 2 > ../my_dir/file
cat ./file
cat $PWD/file
rm -r ../my_dir
It will output:
1
cat: ./file: No such file or directory
2
i.e. $PWD/file has changed.

./mv.sh: line 4: cd: 1.4-1.5.csh: Not a directory

I want to move file1 to directory1 in many subdirectories of current directory. Both file1 and directory1 are in each subdirectory. I write the following script in current directory but it reports "./mv.sh: line 4: cd: directory1: No such file or directory". Actually, the directory1 is in each subdirectory.
1 #!/bin/bash
2
3 for i in *; do
4 builtin cd $i
5 mv file1 directory1
6 builtin cd ..
7 done
error
./mv.sh: line 4: cd: directory1: No such file or directory
mv: cannot stat `file1': No such file or directory
Is it possible that directory1 is a dangling symbolic link? For example:
mkdir foo
ln -s foo foolink
mv foo bar # foolink still points to foo but foo is gone!
cd foolink
# bash: cd: foolink: No such file or directory
Also, instead of
cd dir
mv foo subdir
cd ..
I would recommend the more succinct, and more importantly, safer version:
mv dir/foo dir/subdir/
Why is this safer? Imagine that dir doesn't exist:
cd dir # Fails
mv foo subdir # Oops! Now we're trying to move a file from the current directory
cd .. # Even bigger oops! Now we're even higher in the directory tree,
# and on the next iteration will be moving files around that we
# shouldn't be
(You could also avert this issue in this particular case by using set -o errexit but in general cd .. in scripts is dangerous, in my opinion.)
Also, as Ansgar Wiechers said, you should use find instead of trying to crawl the tree yourself.
I'd use find rather than trying to crawl the directory tree:
find . -type f -name "file1" -execdir mv {} directory1/ \;
This assumes that each directory with a file file1 has a subdirectory directory1.
I suppose the cd .. in line 6 lead you to another directory. You can check this by inserting builtin pwd between lines 6 and 7. This shows you in which directory you actually are after the cd ...
Maybe one of the directories is in fact a link to another directory? This could be the reason for landing somewhere you did not expect.
If the cd $i fails, you could also land in a wrong directory, this may happen if $i is not a directory or you don't have permission to explore it.

Copy and overwrite a file in shell script

I want to copy a certain file to a location, irrespective of that file already exists in the destination or not. I'm trying to copy through shell script.But the file is not getting copied. I'm using the following command
/bin/cp -rf /source/file /destination
but that doesn't work.
Use
cp -fr /source/file /destination
this should probably solve the problem.
This question has been already discussed, however you can write a little script like this:
#!/bin/bash
if [ ! -d "$2" ]; then
mkdir -p "$2"
fi
cp -R "$1" "$2"
Explaining this script a little bit
#!/bin/bash: tells your computer to use the bash interpreter.
if [ ! -d "$2" ]; then: If the second variable you supplied does not already exist...
mkdir -p "$2": make that directory, including any parent directories supplied in the path.
Running mkdir -p one/two/three will make:
$ mkdir -p one/two/three
$ tree one
one/
└── two
└── three
If you don't supply the -p tag then you'll get an error if directories one and two don't exist:
$ mkdir one/two/three
mkdir: cannot create directory ‘one/two/three’: No such file or directory
fi: Closes the if statement.
cp -R "$1" "$2": copies files from the first variable you supplied to the directory of the second variable you supplied.
So if you ran script.sh mars pluto, mars would be the first variable ($1) and pluto would be the second variable ($2).
The -R flag means it does this recursively, so the cp command will go through all the files and folders from your first variable, and copy them to the directory of your second variable.
Your problem might be caused by an alias for cp command created in your system by default (you can see al your aliases by typing "alias").
For example, my system has the following alis by default: alias cp='cp -i', where -i overrides -f option, i.e. cp will always prompt for overwriting confirmation.
What you need in such case (that'll actually work even if you don't have an alias) is to feed "yes" to that confirmation. To do that simply modify your cp command to look like this:
yes | cp /source/file /destination
/bin/cp -rf src dst
or
/usr/bin/env cp -rf

Resources