get folder name with find ... -name command in bash - bash

Trying to get name of venv folder for activating it in bash script located inside the project. Because someone could use for venv another name like 'someones_env'
projectdir=$(cd ../../ && pwd)
echo "$(dirname "$projectdir")"
venvdir=$(find "$(dirname "$projectdir")" -name '*env')
echo "$(dirname "$venvdir")"
source "$(dirname "$venvdir")"/bin/activate
but $venvdir becomes the same as $projectdir instead of 'someones_env'
what am i doing wrong?
thanks

The directory of the *env folder is the project directory, that's why dirname "$venvdir" becomes the same as the project directory. Without dirname it should work.
Also, the directory of ../../ is ../../../, this might also be giving you some issues. If you are already in a directory, there's no need to use dirname. dirname calculates the parent directory.

Related

tar one folder to an other directory

I'm trying to create a bash script that creates an archive of one folder (or the folder content) to a specific directory.
My version works but instead to archive one folder it archives me the whole path which I don't want.
Is there a way to solve this problem without using cd? I saw some solutions using -C but I get the following error, no matter where I place it: refusing to create an empty archive
SRCDIR=~/Documents/sub1/sub2/sub3/source/*
DESTDIR=~/Documents/sub1/sub2/sub3/target/backup.tgz
tar czf $DESTDIR --absolute-names $SRCDIR
You can try this:
SRCDIR=~/Documents/sub1/sub2/sub3/source/*
DESTDIR=~/Documents/sub1/sub2/sub3/target/backup.tgz
tar czf $DESTDIR --absolute-names -C $(dirname $SRCDIR) $(basename $SRCDIR)
As you can see in my example I'm using -C option to change the directory in combination with dirname and basename for source directory
OTHER OPTIONS
-C, --directory DIR
change to directory DIR
Usually, when the '-C' is being used, the wild-card expansion does not work well - as it will try to expand the wildcard ('*' in this case) at the current directory where the command is invoked, and NOT at the SRCDIR location.
If you want all files to be included in the repository, use the '.' (it will also include hidden files!).
SRCDIR=~/Documents/sub1/sub2/sub3/source/*
DESTDIR=~/Documents/sub1/sub2/sub3/target/backup.tgz
tar czf $DESTDIR -C "$(dirname $SRCDIR)" .
As a side note, the original post is using '--absolute-names'. You might want to reconsider using this flag, as it make it extremely difficult to restore the files into any other location but the original location of the files.

Bash script get one directory back

I can get my current working directory with
my_dir=$(pwd)
echo $my_dir
/files/work/test
How do I get /files/work I don't want to change directories. I just need to get the /files/work directory.
Try one of these (assuming you didn't manually change $PWD):
echo "${PWD%/*}"
dirname "$PWD"
(cd .. && pwd)
echo `dirname \`pwd\``
It ll result the parent directory of present working directory
You can ascend one directory above:
$ cd ..
or you can dirname to print the one directory above:
$ dirname "/files/work/test"
/files/work

Unable to use dirname within subshell in find command

I am trying to make a small script that can move all files from one directory to another, and I figured using find would be the best solution. However, I have run into a problem of using subshells for the 'dirname' value in creating the target directory paths. This does not work because {} evaluates to '.' (a single dot) when inside a subshell. As seen in my script bellow, the -exec mkdir -p $toDir/$(dirname {}) \; portion of the find command is what does not work. I want to create all of the target directories needed to move the files, but I cannot use dirname in a subshell to get only the directory path.
Here is the script:
#!/bin/bash
# directory containting files to deploy relative to this script
fromDir=../deploy
# directory where the files should be moved to relative to this script
toDir=../main
if [ -d "$fromDir" ]; then
if [ -d "$toDir" ]; then
toDir=$(cd $toDir; pwd)
cd $fromDir
find * -type f -exec echo "Moving file [$(pwd)/{}] to [$toDir/{}]" \; -exec mkdir -p $toDir/$(dirname {}) \; -exec mv {} $toDir/{} \;
else
echo "A directory named '$toDir' does not exist relative to this script"
fi
else
echo "A directory named '$fromDir' does not exist relative to this script"
fi
I know that you can us -exec sh -c 'echo $(dirname {})' \;, but with this, I would then not be able to use the $toDir variable.
Can anyone help me figure out a solution to this problem?
Since you appear to be re-creating all the files and directories, try the tar trick:
mkdir $toDir
cd $fromDir
tar -cf - . | ( cd $toDir ; tar -xvf - )

Retrieve parent directory of script

I'm working on an uninstaller script to delete the parent folder where the script is installed.
/usr/local/Myapplication/Uninstaller/uninstall.sh
So uninstall.sh has to do this:
rm- rf /usr/local/Myapplication
I can retrieve the folder where uninstall resides
SYMLINKS=$(readlink -f "$0")
UNINSTALL_PATH=$(dirname "$SYMLINKS")
But I'm still unsure of the pretty way to get the parent path.
I thought of using sed to demove the "Uninstaller" part of this path, but is there an elegant way to get the path to Myapplication folder to delete it?
Thank you
How about using dirname twice?
APP_ROOT="$(dirname "$(dirname "$(readlink -fm "$0")")")"
The quoting desaster is only necessary to guard against whitespace in paths. Otherwise it would be more pleasing to the eye:
APP_ROOT=$(dirname $(dirname $(readlink -fm $0)))
I put this answer as comment at 2018. But since I got a great feedback about the effectiveness of the solution, I will share it here as well :
# dir of script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
# parent dir of that dir
PARENT_DIRECTORY="${DIR%/*}"
Just get the parent of the parent directory:
my_app_path=$(dirname $(dirname $(readlink -f "$0")))
If you need an absolute path, then you need cd. Otherwise you can just use $(dirname $0)/..
cd $(dirname $0)/..
path=$(pwd)
cd - # go back
the ultimate simple way of getting the parent directory path:
PARENT_DIRECTORY="${PWD%/*}"
Full path to parent dir of script, i.e. "/usr/local/bin/bla": export PARENT_OF_THIS_SCRIPT=$( cd $(dirname $0) ; pwd -P )
Just the most recent parent of script, i.e. "bla": export PARENT_DIR_OF_SCRIPT=$( cd $(dirname $0) ; pwd -P | xargs basename )
Why don't you simply add ../ at the end of the path?
As $0 can have suprising behavior, here is a solution using BASH_SOURCE[0]:
#/bin/bash
PARENT_DIR=$(dirname $(dirname $(readlink -f "${BASH_SOURCE[0]}")))

Change directories

I am having some trouble in doing some comands on shell.
My problem is that I want to change directories more specifically to a directory which I don't know but that contains the file named xxx.
How can I change directly to that directory that contains that file?
If I knew the names of the directories that contained that file would be easier because I only had to use cd ~/Name of directory.
Can anyone help me?
thanks
If you have GNU find:
cd "$(find /startdir -name 'filename' -printf %h -quit)"
You can replace "/startdir" with any valid directory, for example /, . or `~/.
If you want to cd to a directory which is in the $PATH that contains an executable file:
cd "$(dirname "$(type -P "filename")")" # Bash
or
cd "$(f=$(type -P "ksh"); echo "${f%/*}")" # Bash
or
cd "$(dirname "$(which "filename")")"
If you don't know where a file is, go to the root of the system and find it:
cd /
find . -iname filename
In several linux systems you could do:
$ cd `find . -name "filename" | xargs dirname`
But change "filename" to the file you want to find.
BASH
cd `find . -name "*filename*" | head -1`
This is kind of a variation to Qiau answer. Finds the first file which contains the string filename and then change the current directory to its location.
* is a wild card, there may be something before and/or after filename.

Resources