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

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

Related

Not unzipping all files while using 7z in shell script

I am using below command
echo "A"|7z x -r -y /usr/sap/Silentinstall/commerce/commerce.7z.001
When I ran it from linux machine i.e. from cmd it works and it unzips all the files and folders.
But It it not extracting full files and folder when I am running it in shell script as below
#!/bin/sh
cd /usr/sap/Silentinstall/commerce
echo "A"|7z x -r -y /usr/sap/Silentinstall/commerce/commerce.7z.001
chmod -R 777 /usr/sap/Silentinstall/*
After lot of approaches i found below Solution,
cd /usr/sap/Silentinstall/commercedownloads
7z x /usr/sap/Silentinstall/commercedownloads/testcomm.7z.001 -o/usr/sap/Silentinstall/commercedownloads -aoa -r >>/usr/sap/Silentinstall/commercedownloads/log.txt
chmod -R 777 /usr/sap/*

How to make shell script executable after decompress without chmod

I am studying linux, and I have to make all shell scripts executable by this command:
find ./ -name "*.sh" -exec chmod u+x {} \;
But when I download Logstash.tar.gz and extract it to /opt, all shell scripts were executable, no chmod needed. And /opt is not in $PATH.
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin
How do I build an app like logstash works?
===updated test steps for verification===
mkdir testtar && cd testtar
## create a executable script
echo test_with_x >> test_with_x.sh
chmod u+x test_with_x.sh
## create a not executable script
echo test_without_x >> test_without_x.sh
cd ..
## compress with gzip
tar -zcvf testtar.tar.gz ./testtar
mkdir testextract
mv testtar.tar.gz ./testextract
cd ./testextract
tar -zxvf testtar.tar.gz
## decompressed and see a executable and not executable script
Logstash tar bundle might have been created with executable permissions on all scripts. It should be the reason why it works fine after extracting without using chmod u+x command. If you also create a tar bundle with executable scripts, you should also get executable scripts after decompressing without using chmod u+x.
If you want your shell scripts to be executed without using chmod u+x, provide your shell script as an argument to your shell interpreter.
For e.g,
bash MyScript.sh
sh MyScript.sh
ksh MyScript.sh
You have two solution:
Add /opt to the PATH:
export PATH=${PATH}:/opt
call logstash with full path:
/opt/<anywhere.it.may.be>/logstash

Sync file permissions *only*

A junior team member did a nasty chmod -R 777 in /etc/ and cause SSH cannot login remotely in a Ubuntu server. Now I fixed this login issue by manually set the correct file permissions on /etc/ssh/*, /etc/sudoers, /etc/ssl/* by comparing other normal system. But there are so many other files which may cause future issues.
I am thinking to use rsync to do the work, but don't want it to sync file contents, just permissions, no more work.
Is that possible? I see rsync has -a option but it does too much.
If you have the "normal" content of /etc available on the same system (like mounted in some other directory, let's say /mnt/correct/etc), you could use the --reference parameter to chmod and chown commands, and combine it with find that is started from the "normal" directory:
$ cd /mnt/correct/etc
$ find . ! -type l -exec chown -v --reference='{}' /etc/'{}' \;
$ find . ! -type l -exec chmod -v --reference='{}' /etc/'{}' \;
(I'm assuming you're on a UNIX system with GNU coreutils versions of chmod and chown.)
The "! -type l" condition in find excludes symbolic links, because otherwise chmod will use the link's permissions to change the file the link points to (and same applies to chown).
Please note you can also try something that won't necessarily make you need to copy files from one place to another (depending on the filesize it may be desired)
You could use a mix of find and some grepping to generate a shell script to be executed on the host where you need to fix permissions.. you could use the same approach to generate a script for changing users/groups as well.. for example:
# find . -printf 'chmod %m %p #%M\n' | sort -k3 | grep -Pi '\s+\S*s\S*$' > /var/tmp/fix_permissions.bash
# bash /var/tmp/fix_permissions.bash
In the example above, what it does is to list all the files with their attributes in this format:
chmod 2755 ./addfs_7.1.0/bin #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/config #drwxr-sr-x
chmod 2755 ./addfs_7.1.0 #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/install #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/library.dda #drwxr-sr-x
chmod 2755 ./addfs_7.1.0/library #drwxr-sr-x
chmod 2755 ./autosimimport #drwxr-sr-x
And in my case I only want to sync those with the 's' flag, so I filter with grep -Pi '\s+\S*s\S*$'. Sort was there as well because I had to compare the files in the other host.
TLDR
If you just want to apply all the permissions with no filtering or comparing:
Create a script with the correct permissions on the "base" host
find . -printf 'chmod %m %p\n' > /var/tmp/fix_permissions.sh
Execute the script in the other host
bash /var/tmp/fix_permissions.sh

Copying files with wildcard (*) to a folder in a bash script - why isn't it working?

I am writing a bash script that creates a folder, and copies files to that folder. It works from the command line, but not from my script. What is wrong here?
#! /bin/sh
DIR_NAME=files
ROOT=..
FOOD_DIR=food
FRUITS_DIR=fruits
rm -rf $DIR_NAME
mkdir $DIR_NAME
chmod 755 $DIR_NAME
cp $ROOT/$FOOD_DIR/"*" $DIR_NAME/
I get:
cp: cannot stat `../food/fruits/*': No such file or directory
You got that exactly backwards -- everything except the * character should be double-quoted:
#!/bin/sh
dir_name=files
root=..
food_dir=food
fruits_dir=fruits
rm -rf "$dir_name"
mkdir "$dir_name"
chmod 755 "$dir_name"
cp "$root/$food_dir/"* "$dir_name/"
Also, as a matter of best-practice / convention, non-environment variable names should be lower case to avoid name conflicts with environment variables and builtins.

How do I exclude a folder when performing file operations i.e. cp, mv, rm and chown etc. in Linux

How do you exclude a folder when performing file operations i.e. cp etc.
I would currently use the wild card * to apply file operation to all, but I need to exclude one single folder.
The command I'm actually wanting to use is chown to change the owner of all the files in a directory but I need to exclude one sub directory.
If you're using bash and enable extglob via shopt -s extglob then you can use !(<pattern>) to exclude the given pattern.
find dir_to_start -name dir_to_exclude -prune -o -print0 | xargs -0 chown owner
find dir_to_start -not -name "file_to_exclude" -print0 | xargs -0 chown owner
for file in *; do
if [ $file != "file_I_dont_want_to_chown" ]
then
chown -R Camsoft $file
fi
done
Combine multiple small sharp tools of unix:
To exclude the folder "foo"
% ls -d * | grep -v foo | xargs -d "\n" chown -R Camsoft
For this situation I would recommend using find. You can specify paths to exclude using the -not -iwhilename 'PATH'. Then using exec you execute the command you want to execute
find . -not -iwholename './var/foo*' -exec chown www-data '{}' \;
Although this probably does help for your situation I have also see scripts set the immutable flag. Make sure you remove the flag when your done you should use trap for this just in case the script is killed early (note: run from a script, the trap code runs when the bash session exits). A lot of trouble in my option but it's good in some situations.
cd /var
trap 'chattr -R -i foo > /dev/null 2>&1' 0
chattr -R +i foo
chown -R www-data *
Another option might be to temporarily remove permission on the that file /folder.
In Unix you need 'x' permission on a directory to enter it.
edit: obviously this isn't goign to work if you are backing up a live production database - but for excluding your 'interesting images' collection when copying documents to a USB key it's reasoanable.

Resources