• Important: We recently upgraded our forum software - please let us know if you run into any issues.

Shell script question

hawruh

New Member
Hi, I have a very simple (I think) question about how to create this shell script.

https://pastebin.com/RbNc0iRv

All I want to do is:

Untar an archive, cd into the new directiory. Something is not working (the cd). Any help is much appreciated!
 


BRVN01

New Member
Hello friend,
If you put the shebang '#!/bin/sh -x', you will see a detailed description line by line, with this I could notice that SH is giving error in if brackets, just remove one of the brackets that everything will work.

Test:
$ ./teste dns
+ PACKAGE=dns
+ grep dns
+ ls ./
+ DIR=dns.tar.gz
+ tar -xf dns.tar.gz
+ grep dns
+ ls ./
+ DIR2=dns
dns.tar.gz
+ [[ -d dns ]]
./teste: 23: ./teste: [[: not found
+ [[ -d dns.tar.gz ]]
./teste: 23: ./teste: [[: not found

How to let:

for file in $DIR2
do
if [ -d $file ]; then
echo $file
PACKAGE_DIR=$file
# Tried this first, didn't work
#cd $file
fi

done


Ps: Apologies for writing, I do not speak your language.
 
Last edited:

JasKinasis

Well-Known Member
Hi, I have a very simple (I think) question about how to create this shell script.

https://pastebin.com/RbNc0iRv

All I want to do is:

Untar an archive, cd into the new directiory. Something is not working (the cd). Any help is much appreciated!
From quickly testing your script - it appears to be working fine for me.
I put a random .tar.gz archive in a test directory, along with your script.
And where the name of the archive was filename.tar.gz, I ran your script as:
Code:
./nameofscript.sh filename
The .tar.gz was extracted and the final cd command IS working.
You can verify this by putting the following lines at the end of your script:
Code:
pwd
ls -Alh
Adding those two lines you should see that we ARE inside the extracted directory and that we CAN see the content of the extracted directory.

So your script works.

If you mean that the shell you have just executed the script in hasn't entered the extracted directory - that is because your script is being executed in a sub-shell. So it is executed in a different environment.

To execute the script in the current environment, you would need to save it somewhere as a function:
e.g. ~/bin/extractpackage.sh
Code:
function ExtractPackage
{
# Does the following:
# 1. Untars the package archive
# 2. cd into the new package directory
# Assign the package name to the first passed in command line parameter
PACKAGE="$1"
# Find the package archive
DIR="$(ls ./ | \grep $PACKAGE)"
# Untar the archive
tar -xf "$DIR"
# Get the items in a variable (archive + new untarred directory)
DIR2="$(ls ./ | \grep $PACKAGE | \grep -v '.tar')"
# If the file is a dicectory, that is the one we want to enter so save it in a variable (NOTE: tried cd'ing in loop, that didn't work either)
for file in "$DIR2"
do
    if [[ -d "$file" ]]; then
        PACKAGE_DIR="$file"
    fi
done
cd "$PACKAGE_DIR"
}
NOTE: In the above function we have used \grep instead of grep. This will escape any aliases that have been set for grep.

For example, you may have grep aliased in your .bashrc to include line-numbers or other types of formatted output that we are not interested in.
So to ensure we are using pure grep with no extra parameters, we prepend a backslash and avoid using any aliases.

Anyway - with your function saved in a script-file - the next part of the puzzle is to edit your .bashrc to source the file containing the function.
To do this, you would open your existing .bashrc and add a line like this to it:
Code:
source ~/bin/extractpackage.sh
After saving your .bashrc and quitting your editor, you will then need to reload it into the current shell using the dot command (equivalent to the source command):
Code:
. ~/.bashrc
Now you can use your function in the current shell's environment.
Code:
ExtractPackage nameofarchive
Where nameofarchive is the name of a tar file in the current directory. e.g. nameofarchive.tar.gz, or nameofarchive.tar.xz etc.

That should find the .tar file (or .tar.gz, or whatever), extract it and cd into the newly created directory.


But you should also note that the code in the function is quite brittle - it's far from bullet-proof.
Your script will need a few tweaks and adjustments to allow it to cope with various adverse situations.
e.g. if no parameters are passed, it should probably display some usage info and quit.

Also, if you had two archives called:
archive-v1.tar.gz
archive-v2.tar.gz
and you ran the command:
Code:
ExtractPackage archive
The first grep command in the function will list both of the .tar.gz files and then the tar command will most likely fail. So you should probably do something in your script if more than one target is found for the package-name.

There are probably a number of other potential problems with your script. But I will leave it to you to continue playing with it and working out what you want to do.

But putting your code into a function that is loaded via .bashrc is probably the best way to get a script to affect the current execution environment. Otherwise, scripts get executed in their own environment in a sub-shell, without affecting the parent-shells environment!
 

Members online


Top