changing folder permissions to admin - linux

I have a bash script to create and move files
This script is making folder bassed on file name and then create another folder downloads
example movie.mkv
movie/downloads/movie.mkv
for file in *.mkv; do
folder=$(basename "$file" ".mkv")"/downloads"
mkdir -p "$folder" && mv "$file" "$folder"
done
but folders created by this script have root permissions and I need admin permissions
Is there any way to edit this script?
Here is a picture what I want to change:
http://s5.postimg.org/5cmxxf8on/Bez_tytu_u.jpg
Best Regards and THank You

Since you're running script as root you can add chown command as the last command in script to change owner to admin:
for file in *.mkv; do
folder=$(basename "$file" ".mkv")"/downloads"
mkdir -p "$folder" && mv "$file" "$folder"
chown -R admin "$folder"
done

Related

mkdir: cannot create directory No such file or directory

I can't find a solution for this problem. I am trying to write a script that creates a folder, which name is the current date, with all content of the current directory so I can backup a bunch of files. I tried following things already that doesn't work:
use "mkdir -p" to create parent directories
not using relative path with "pwd"
But when I try and create a directory out of an script in the terminal(also bash) I can create perfectly fine directories with the date inside. (following command)
mkdir backup$(date +%d-%m-%Y_%H:%M)
My Code
#!/bin/bash
DATE=$(date +%d-%m-%Y_%H:%M)
PWD=$(pwd)
FILENAME=backup$DATE
if [ -d "backup/" ]; then
mkdir -p backup/$FILENAME
cp -r * backup/$FILENAME
else
mkdir -p backup/
mkdir -p backup/$FILENAME
cp -r * backup/$FILENAME
fi
Error thrown
mkdir: cannot create directory ‘backup/backup18-01-2022_12:43’: No such file or directory

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"

How to write a shell (.sh) script for the following

I'm new to linux/unix shell scripting, and I have a few dozen projects that I want to set up Subversion folders for (eventually I'll get to Git lol). How do I write a script to do the following:
Get a list of all sub-folders in a folder
For each sub-folder, use it execute the following commands:
svnadmin create /var/www/svn/<sub-folder>
svn import /var/www/<sub-folder> file:///var/www/svn/<sub-folder>
chmod -R 777 var/www/svn/<sub-folder>
chown -R apache.apache var/www/svn/<sub-folder>
From what I've seen on the internet so far, I suppose I put it all into a .sh file and type something like :
.sh thing.sh
... to execute it.
Any help appreciated.
for i in `find -maxdepth 1 -type d`; do
svnadmin create "/var/www/svn/$i"
svn import "/var/www/$i" "file:///var/www/svn/$i"
chmod -R 777 "var/www/svn/$i"
chown -R apache.apache "var/www/svn/$i"
done
Of course your svn import command is incorrect, and pathes in your chmod and chown missing /. But it's copypaste of your commands, anyway.
Does this work for you?
#!/bin/bash
for FILE in `ls`
do
if test -d $FILE
then
svnadmin create /var/www/svn/$FILE
svn import /var/www/$FILE file:///var/www/svn/$FILE
chmod -R 777 /var/www/svn/$FILE
chown -R apache.apache /var/www/svn/$FILE
fi
done
After saving execute chmod +x {name of file} on the script to make it executable with ./{name of file} or sh {name of file}.
In case you need all subfolders recursively from current folder:
#!/bin/bash
for FILE in `find . -type d`
do
if test -d $FILE
then
svnadmin create /var/www/svn/$FILE
svn import /var/www/$FILE file:///var/www/svn/$FILE
chmod -R 777 /var/www/svn/$FILE
chown -R apache.apache /var/www/svn/$FILE
fi
done
If you have any questions please comment.
You could create a script doIt.sh with the following:
#!/bin/bash
svnadmin create /var/www/svn/$1
svn import /var/www/$1 file:///var/www/svn/$1
chmod -R 777 var/www/svn/$1
chown -R apache.apache var/www/svn/$1
Then you can go into the folder in which you want to find all subfolders and execute the following:
find . -type d | xargs -I {} ./doIt.sh {}
Also, are you sure of this line:
svn import /var/www/<sub-folder> file:///var/www/svn/<sub-folder>
Did you not mean:
svn import /var/www/svn/<sub-folder> file:///var/www/svn/<sub-folder>
Note: Missing svn subfolder in path

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

Is there a way to make mv create the directory to be moved to if it doesn't exist?

So, if I'm in my home directory and I want to move foo.c to ~/bar/baz/foo.c , but those directories don't exist, is there some way to have those directories automatically created, so that you would only have to type
mv foo.c ~/bar/baz/
and everything would work out? It seems like you could alias mv to a simple bash script that would check if those directories existed and if not would call mkdir and then mv, but I thought I'd check to see if anyone had a better idea.
How about this one-liner (in bash):
mkdir --parents ./some/path/; mv yourfile.txt $_
Breaking that down:
mkdir --parents ./some/path
# if it doesn't work; try
mkdir -p ./some/path
creates the directory (including all intermediate directories), after which:
mv yourfile.txt $_
moves the file to that directory ($_ expands to the last argument passed to the previous shell command, ie: the newly created directory).
I am not sure how far this will work in other shells, but it might give you some ideas about what to look for.
Here is an example using this technique:
$ > ls
$ > touch yourfile.txt
$ > ls
yourfile.txt
$ > mkdir --parents ./some/path/; mv yourfile.txt $_
$ > ls -F
some/
$ > ls some/path/
yourfile.txt
mkdir -p `dirname /destination/moved_file_name.txt`
mv /full/path/the/file.txt /destination/moved_file_name.txt
Save as a script named mv.sh
#!/bin/bash
# mv.sh
dir="$2" # Include a / at the end to indicate directory (not filename)
tmp="$2"; tmp="${tmp: -1}"
[ "$tmp" != "/" ] && dir="$(dirname "$2")"
[ -a "$dir" ] ||
mkdir -p "$dir" &&
mv "$#"
Or put at the end of your ~/.bashrc file as a function that replaces the default mv on every new terminal. Using a function allows bash keep it memory, instead of having to read a script file every time.
function mvp ()
{
dir="$2" # Include a / at the end to indicate directory (not filename)
tmp="$2"; tmp="${tmp: -1}"
[ "$tmp" != "/" ] && dir="$(dirname "$2")"
[ -a "$dir" ] ||
mkdir -p "$dir" &&
mv "$#"
}
Example usage:
mv.sh file ~/Download/some/new/path/ # <-End with slash
These based on the submission of Chris Lutz.
You can use mkdir:
mkdir -p ~/bar/baz/ && \
mv foo.c ~/bar/baz/
A simple script to do it automatically (untested):
#!/bin/sh
# Grab the last argument (argument number $#)
eval LAST_ARG=\$$#
# Strip the filename (if it exists) from the destination, getting the directory
DIR_NAME=`echo $2 | sed -e 's_/[^/]*$__'`
# Move to the directory, making the directory if necessary
mkdir -p "$DIR_NAME" || exit
mv "$#"
It sounds like the answer is no :). I don't really want to create an alias or func just to do this, often because it's one-off and I'm already in the middle of typing the mv command, but I found something that works well for that:
mv *.sh shell_files/also_with_subdir/ || mkdir -p $_
If mv fails (dir does not exist), it will make the directory (which is the last argument to the previous command, so $_ has it). So just run this command, then up to re-run it, and this time mv should succeed.
The simpliest way to do that is:
mkdir [directory name] && mv [filename] $_
Let's suppose I downloaded pdf files located in my download directory (~/download) and I want to move all of them into a directory that doesn't exist (let's say my_PDF).
I'll type the following command (making sure my current working directory is ~/download):
mkdir my_PDF && mv *.pdf $_
You can add -p option to mkdir if you want to create subdirectories just like this: (supposed I want to create a subdirectory named python):
mkdir -p my_PDF/python && mv *.pdf $_
Making use of the tricks in "Getting the last argument passed to a shell script" we can make a simple shell function that should work no matter how many files you want to move:
# Bash only
mvdir() { mkdir -p "${#: -1}" && mv "$#"; }
# Other shells may need to search for the last argument
mvdir() { for last; do true; done; mkdir -p "$last" && mv "$#"; }
Use the command like this:
mvdir foo.c foo.h ~/some/new/folder/
rsync command can do the trick only if the last directory in the destination path doesn't exist, e.g. for the destination path of ~/bar/baz/ if bar exists but baz doesn't, then the following command can be used:
rsync -av --remove-source-files foo.c ~/bar/baz/
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose increase verbosity
--remove-source-files sender removes synchronized files (non-dir)
In this case baz directory will be created if it doesn't exist. But if both bar and baz don't exist rsync will fail:
sending incremental file list
rsync: mkdir "/root/bar/baz" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(657) [Receiver=3.1.2]
So basically it should be safe to use rsync -av --remove-source-files as an alias for mv.
The following shell script, perhaps?
#!/bin/sh
if [[ -e $1 ]]
then
if [[ ! -d $2 ]]
then
mkdir --parents $2
fi
fi
mv $1 $2
That's the basic part. You might want to add in a bit to check for arguments, and you may want the behavior to change if the destination exists, or the source directory exists, or doesn't exist (i.e. don't overwrite something that doesn't exist).
Sillier, but working way:
mkdir -p $2
rmdir $2
mv $1 $2
Make the directory with mkdir -p including a temporary directory that is shares the destination file name, then remove that file name directory with a simple rmdir, then move your file to its new destination.
I think answer using dirname is probably the best though.
This will move foo.c to the new directory baz with the parent directory bar.
mv foo.c `mkdir -p ~/bar/baz/ && echo $_`
The -p option to mkdir will create intermediate directories as required.
Without -p all directories in the path prefix must already exist.
Everything inside backticks `` is executed and the output is returned in-line as part of your command.
Since mkdir doesn't return anything, only the output of echo $_ will be added to the command.
$_ references the last argument to the previously executed command.
In this case, it will return the path to your new directory (~/bar/baz/) passed to the mkdir command.
I unzipped an archive without giving a destination and wanted to move all the files except demo-app.zip from my current directory to a new directory called demo-app. The following line does the trick:
mv `ls -A | grep -v demo-app.zip` `mkdir -p demo-app && echo $_`
ls -A returns all file names including hidden files (except for the implicit . and ..).
The pipe symbol | is used to pipe the output of the ls command to grep (a command-line, plain-text search utility).
The -v flag directs grep to find and return all file names excluding demo-app.zip.
That list of files is added to our command-line as source arguments to the move command mv. The target argument is the path to the new directory passed to mkdir referenced using $_ and output using echo.
Based on a comment in another answer, here's my shell function.
# mvp = move + create parents
function mvp () {
source="$1"
target="$2"
target_dir="$(dirname "$target")"
mkdir --parents $target_dir; mv $source $target
}
Include this in .bashrc or similar so you can use it everywhere.
Code:
if [[ -e $1 && ! -e $2 ]]; then
mkdir --parents --verbose -- "$(dirname -- "$2")"
fi
mv --verbose -- "$1" "$2"
Example:
arguments: "d1" "d2/sub"
mkdir: created directory 'd2'
renamed 'd1' -> 'd2/sub'
((cd src-path && tar --remove-files -cf - files-to-move) | ( cd dst-path && tar -xf -))
I frequently stumble upon this issue while bulk moving files to new subdirectories. Ideally, I want to do this:
mv * newdir/
Most of the answers in this thread propose to mkdir and then mv, but this results in:
mkdir newdir && mv * newdir
mv: cannot move 'newdir/' to a subdirectory of itself
The problem I face is slightly different in that I want to blanket move everything, and, if I create the new directory before moving then it also tries to move the new directory to itself. So, I work around this by using the parent directory:
mkdir ../newdir && mv * ../newdir && mv ../newdir .
Caveats: Does not work in the root folder (/).
My one string solution:
test -d "/home/newdir/" || mkdir -p "/home/newdir/" && mv /home/test.txt /home/newdir/
i accomplished this with the install command on linux:
root#logstash:# myfile=bash_history.log.2021-02-04.gz ; install -v -p -D $myfile /tmp/a/b/$myfile
bash_history.log.2021-02-04.gz -> /tmp/a/b/bash_history.log.2021-02-04.gz
the only downside being the file permissions are changed:
root#logstash:# ls -lh /tmp/a/b/
-rwxr-xr-x 1 root root 914 Fev 4 09:11 bash_history.log.2021-02-04.gz
if you dont mind resetting the permission, you can use:
-g, --group=GROUP set group ownership, instead of process' current group
-m, --mode=MODE set permission mode (as in chmod), instead of rwxr-xr-x
-o, --owner=OWNER set ownership (super-user only)
There's a lot of conflicting solutions around for this, here's what worked for us:
## ss_mv ##
function ss_mv {
mkdir -p $(dirname "$2") && mv -f "$#"
}
This assumes commands in the following syntax:
ss_mv /var/www/myfile /var/www/newdir/myfile
In this way the directory path /var/www/newdir is extracted from the 2nd part of the command, and that new directory is then created (it's critical that you use the dirname tag to avoid myfile being added to the new directory being created).
Then we go ahead and mv on the entire string again by using the "$#" tag.
You can even use brace extensions:
mkdir -p directory{1..3}/subdirectory{1..3}/subsubdirectory{1..2}
which creates 3 directories (directory1, directory2, directory3),
and in each one of them two subdirectories (subdirectory1, subdirectory2),
and in each of them two subsubdirectories (subsubdirectory1 and subsubdirectory2).
You have to use bash 3.0 or newer.
$what=/path/to/file;
$dest=/dest/path;
mkdir -p "$(dirname "$dest")";
mv "$what" "$dest"

Resources