Bash script to change directory from user input - bash

Whenever I execute this script it says: no such file or directory.
I'm not sure what I'm doing wrong here. I put quotes around it just in case if there is a space in the directory's name.
#!/bin/bash
read -p "Enter destination: " folder
folder=$(sed -e 's/^/"/' -e 's/$/"/' <<< $folder)
cd $folder

It is better to use quotes in the cd command, regardless of whether the directory has spaces or not, like this:
#!/bin/bash
read -p "Enter destination: " folder
cd "$folder"
pwd
Test:
Another solution (use with caution as it may cause other problems) is using eval in your code:
#!/bin/bash
read -p "Enter destination: " folder
folder=$(sed -e 's/^/"/' -e 's/$/"/' <<< $folder)
eval cd $folder
References:
Bash script to cd to directory with spaces in pathname

Related

How to move all folders in a directory with mv and bash variables

I wanted to take paths to directories from files that we got from a user as parameters of function and from files extract the paths and move all files and folders in the source directory to the destination directory, but something went wrong: It writes to me, that "No such file or directory"
With this input
Where dest_adr.txt contains this path: C:\Users\Michal\Desktop\tmp and source_adr.txt contains this path: C:\Users\Michal\Desktop\test\
#!/bin/bash
FILE_WITH_ADRESS_TO_BLENDER_PATH=$1
FILE_WITH_ADRESS_TO_FOLDER_WITH_ADDONS=$2
function move_folders(){
mv "${PATH_TO_FOLDER_WITH_ADDONS_}"/* "${PATH_TO_BLENDR_DIRECTORIE_}"/
}
if [ $# -eq 0 ]
then
PATH_TO_BLENDR_DIRECTORIE="C:/Program Files/Blender Foundation/Blender 3.0/3.0/scripts/addons"
FOLDER_WITH_ADDONS="none"
echo $PATH_TO_BLENDR_DIRECTORIE
echo $FOLDER_WITH_ADDONS
else
PATH_TO_BLENDR_DIRECTORIE_=$(cat $FILE_WITH_ADRESS_TO_BLENDER_PATH | sed -e 's/\\/\//g' -e 's/\C://g')
PATH_TO_FOLDER_WITH_ADDONS_=$(cat $FILE_WITH_ADRESS_TO_FOLDER_WITH_ADDONS | sed -e 's/\\/\//g' -e 's/\C://g')
echo $PATH_TO_BLENDR_DIRECTORIE_
echo $PATH_TO_FOLDER_WITH_ADDONS_
move_folders
fi
Use Shell Parameter Expansion
adrian#pc:/tmp/move> path_to_file=/usr/share/man/man1/bash.1.gz
adrian#pc:/tmp/move> folder_path=${path_to_file%/*}
adrian#pc:/tmp/move> echo $folder_path
/usr/share/man/man1
adrian#pc:/tmp/move> file_name=${path_to_file##*/}
adrian#pc:/tmp/move> echo $file_name
bash.1.gz
Don't use cat to send variable, it will send content of file no path, use echo or printf instead.
The error occurs because the test/ directory is empty.
Try again with files within it. It's expected behavior to fail with a wildcard if you don't have files in the source directory you are trying to move.
Edit:
Or use mv -r

Script to create directory and subdirectory in sftp

I am running a Bash script to upload the file to an sftp location. However, before uploading the file, I need to check if the sftp directory and sub-directories exist or not. If they exist then upload a file, if not then create the directory and sub-directories and then upload the file. How can I achieve this?
mkdir -p is not working in sftp. Unfortunately the ssh access is disabled. I have tried this:
for i in `ls -1t | head -1`
do
echo $i
zip -r $i_file.zip $i
sleep 2
sshpass -p "passowrd" sftp -oPort=22 username#sftpserver <<< $'cd /file \n mkdir file1/file2/file3 \n cd /file1/file2/file3 \n put '$I_file.zip''
done
First of all, check if the directory exists if not try this, I don't how it will play out using sftp client because I am kind of novice too but thought to give it a try. I would love to hear your feedback or anyone else's for that matter.
#!/bin/bash
path="$1"
if [ ! -d "$path" ]
then
IFS='/' # space is set as delimiter
read -ra ADDR <<< "$path" # str is read into an array as tokens separated by IFS'
cdir="$PWD"
for i in "${ADDR[#]}"; do # access each element of array
cdir+="/$i"
mkdir "$cdir"
done
fi
I have tried this:
for i in `ls -1t | head -1`
do
echo $i
zip -r $i_file.zip $i
sleep 2
sshpass -p "passowrd" sftp -oPort=22 username#sftpserver <<< $'cd /file \n mkdir file1/file2/file3 \n cd /file1/file2/file3 \n put '$I_file.zip''
done
$i_file.zip - If identifier characters are to be appended to the variable expansion, the name must be embraced: ${i}_file.zip.
cd /file \n mkdir file1/file2/file3 \n cd /file1/file2/file3 \n - You change to /file, (try to) create /file/file1/file2/file3 and then try to change to /file1/file2/file3. Perhaps you meant cd /file1 \n mkdir file2 \n mkdir file2/file3 \n cd file2/file3 \n.
$I_file.zip - You have a capital I instead of the lower case i in braces: ${i}_file.zip.

How to "cd" to a directory which is created using "mkdir $(date '+%d-%b-%Y')"

mkdir $(date '+%d-%b-%Y')
then cd to the dynamically created directory
How to "cd" to a directory which is created using "mkdir $(date '+%d-%b-%Y')" and do the operations by moving into the created directory in bash script
Simple way would be, you store the directory name in a variable
dirname=$(date '+%d-%b-%Y')
if [ -n "$dirname" ]; then
mkdir "$dirname"
if [ -d "$dirname" ]; then
cd "$dirname"
fi
fi
Added some error handling and also if your file is written in Windows and being run in an unix environment or vice-versa, I would recommend using dos2unix which will handle the new line character conversions (this is for the ? characters OP is seeing in ls).
Can you show me your case?
In most cases, you should not cd in to the directory. Use absolute path instead:
Good practice:
mkdir /tmp/mydir/
cp -R /usr/local/example/ /tmp/mydir/
sed 's/foo/bar/g' /tmp/mydir/afile
Bad practice:
mkdir /tmp/mydir/
cd /tmp/mydir/
cp -R /usr/local/example/ .
sed 's/foor/bar/g' afile
P.S.
Subj:
$ mkdir $(date '+%d-%b-%Y')
$ cd $(date '+%d-%b-%Y')
$ pwd
/Users/user/18-Feb-2019
In Bash, $_ expands to the last argument to the previous command. So you could do:
mkdir $(date '+%d-%b-%Y')
cd $_
In a real Bash program you would want to quote the expansions (use Shellcheck on your code to check for missing quotes), and check for errors on both mkdir and cd.

LOCAL_DIR variable prepends the scripts current directory (totally not what I expect)

Consider the following simple rsync script I am tryint to slap up:
#!/bin/bash
PROJECT="$1"
USER=stef
LOCAL_DIR="~/drupal-files/"
REMOTE_HOST="hostname.com"
REMOTE_PROJECTS_PATH=""
# Should not have anything to change below
PROJECT_LIST="proj1 proj2 proj3 quit"
echo "/nSelect project you wish to rsync\n\n"
select PROJECT in $PROJECT_LIST
do
if [ "$PROJECT" = "quit" ]; then
echo
echo "Quitting $0"
echo
exit
fi
echo "Rsynching $PROJECT from $REMOTE_HOST into" $LOCAL_DIR$PROJECT
rsync -avzrvP $USER#$REMOTE_HOST:/var/projects/$PROJECT/ $LOCAL_DIR$PROJECT
done
echo "Rsync complete."
exit;
The variable $LOCALDIR$PROJECT set in the rsync command always includes the scripts path, :
OUTPUT:
Rsynching casa from hostname.com.com into ~/drupal-files/casa
opening connection using: ssh -l stef hostname.com rsync --server --sender -vvlogDtprz e.iLsf . /var/groupe_tva/casa/
receiving incremental file list
rsync: mkdir "/home/stef/bin/~/drupal-files/proj1" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(605) [Receiver=3.0.9]
The line with mkdir should not have /home/stef/bin, why is bash adding the script's running dir on the variable?
Thanks
LOCAL_DIR="~/drupal-files/"
The string is in quotes so there's pathname expansion, and the variable will contain the literal string.
Remove the quotes.
$ x="~/test"; echo $x
~/test
$ x=~/test; echo $x
/home/user/test

Prompt for file path: home directory alias and case-sensitive tab completion

I am writing a shell script that prompts the user for a file path:
read -e -p "Enter the path to the file: " FILEPATH
I am then using this file path to perform operations – namely to compress a folder.
(cd "$FILEPATH"; tar -cvz *) > /tmp/torrent.tar.gz;
At the prompt, if I use the ~ alias (home directory), then the shell script doesn't seem to understand this, as the tar function compresses the wrong path. Is there anyway I can allow for this alias?
Also, tab completion seems to be case-sensitive at the prompt. I was wondering how I can change that?
Example using eval:
read -e -p "Enter the path to the file: " FILEPATH
eval FILEPATH=$FILEPATH
cd $FILEPATH
echo $PWD
In your case it becomes:
read -e -p "Enter the path to the file: " FILEPATH
eval FILEPATH=$FILEPATH
(cd "$FILEPATH"; tar -cvz *) > /tmp/torrent.tar.gz;
To deal with spaces you can use sed:
read -e -p "Enter the path to the file: " FILEPATH
FILEPATH=$(echo $FILEPATH | sed 's/ /\\ /')
eval FILEPATH=$FILEPATH
cd "$FILEPATH"
echo $PWD
You could apply the substitution yourself like this:
filepath=${filepath/\~/$HOME}
I don't know whether there's a way to get the shell to do it for you.
Here's an answer to your other question: https://superuser.com/questions/90196/case-insensitive-tab-completion-in-bash

Resources