simple script to remove files in linux bash [duplicate] - linux

This question already has an answer here:
Find "command not found" when executed in bash loop
(1 answer)
Closed 3 years ago.
I made a simple script in linux bash just like bellow:
#!/bin/bash
PATH=/tmp_with_zip_files
FILETYPE=zip
i=1
for filename in $PATH/*.$FILETYPE;
do
echo "rm $filename";
if [ -f $filename ];
then rm $filename;
fi
i=$((i+1))
done
echo "$i files removed"
But, when i run script i have error, because script doesnt work correctly. It's mean from console i have a message:
zip_delete.sh: line 11: rm: command not found
Why linux bash script not recognize linux command rm?

Lol I think it's because you're overwriting the default $PATH variable (which is the variable that tells bash where to look for executables). During execution, it can't find the rm program in PATH because it's pointing to only /tmp_with_zip_files
Use a different variable name for your purposes like chicken_nuggets.
WARNING DON'T DO THE FOLLOWING LMAO PATH=$PATH:/tmp_with_zip_files you could delete a bunch of things from PATH and that would suck really bad

The PATH variable holds the path to OS commands (like rm), don't use that as a variable, name it something else, like path_to_files.

Related

Half of a mkdir function works but cd part doesn't [duplicate]

This question already has answers here:
Why can't I change directories using "cd" in a script?
(33 answers)
Closed 2 years ago.
I've been trying do put together a function that combines mkdir and cd. This is what I've been using:
#!/bin/bash
mk(){
mkdir "$1" && cd "$1"
}
mk $1
However, when I run the script using ./mker.sh test , it'll create a directory with but won't change into it. I'm brand new to Bash so I'm really at a loss as to why that part doesn't work. It doesn't return an error to the command line either.
What's the issue here? Thanks!
When working in / with bash There is no need to cd (it's actually considered "poor form"). cd is "meant" for command line usage -- Though it will work in some cases programmatically, it's easiest and best practice to use the directory when working with it rather than trying to change directory into it.
Simply "use" the full directory to do whatever you intend on "doing" with it .. IE
mkdir "$1" && echo "test" > $1/test.txt
NOTE
In case I read your question wrong, and you want the shell to change directory is a little trickier. The sub-shell (or bash script) has it's own concept of directory .. So no matter "where" you tell it to cd, it will only apply to that sub-shell and not the main shell (or command line). One way to get around this is to use alias
alias dir="cd $M1"

Bash Script is not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
When i am writing the script like this
#!/bin/sh
pidof MX-CM48 | xargs kill
if [ -f /home/root/MX-CM48NEW ]; then
mv /home/root/MX-CM48NEW /home/root/MX-CM48
chmod 777 /home/root/MX-CM48
fi
cd /home/root
./MX-CM48 &
the script is working.
but when i am trying to write it like this:
#!/bin/sh
NEW_FILE="/home/root/MX-CM48NEW"
OLD_FILE="/home/root/MX-CM48"
PATH="/home/root"
APP_NAME="MX-CM48"
pidof $APP_NAME | xargs kill
if [ -f $NEW_FILE ]; then
mv $NEW_FILE $OLD_FILE
chmod 777 $OLD_FILE
fi
cd $PATH
./$APP_NAME &
the pidof and the if are not working.
The PATH environment variable defines where the system looks for the executables corresponding to commands. It's a colon-delimited list of directories that contain executable files, something like /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin. So when you use a command like mv, the system looks for a file named "mv" in /usr/local/bin, then in /usr/bin, then in /bin etc.
When you set PATH to "/home/root" in the script, that then becomes the only place the system will look for command executables. I presume that's not what you wanted at all.
The solution is simple: use a different name for your variable. Actually, it's best to use lower- or mixed-case variable names for your things, because there are a lot of all-caps variable names that have some sort of special meaning and it's hard to remember & avoid all of them.
BTW, you should (almost) always double-quote variable references, e.g. pidof "$APP_NAME" to avoid unexpected weirdness from the way the shell parses unquoted variables. Finally, when you use cd in a script, you should always check for an error; otherwise if the cd command fails, the rest of the script will blindly continue executing in the wrong place.
cd "$path" || {
echo "Error moving to $path directory; giving up" >&2
exit 1
}
"./$app_name" &
Unless you copied all commands to /home/root, it is pretty clear what is wrong.
PATH="/home/root"
should (probably) be:
PATH="$PATH:/home/root"
or use full path-names, like in:
/usr/bin/pidof $APP_NAME | /usr/bin/xargs /bin/kill

How to source more than one bash script from a folder in another script so I can use functions from both of that scrips? [duplicate]

This question already has answers here:
source all files in a directory from .bash_profile
(8 answers)
Closed 4 years ago.
I have run.sh script in a directory. I have also two scripts called d1.sh and d2.sh located in it's subdirectory called deep. I want to source both d1.sh and d2.sh in run.sh script, so I can use "test" function stored in d2.sh.
code of run.sh looks like this:
#!/bin/bash
source ./deep/*
test
d1.sh:
#!/bin/bash
echo -e "d1 is loaded"
d2.sh:
#!/bin/bash
echo -e "d2 is loaded"
test() {
echo -e "test passed!"
}
I execute run.sh with command:
bash run.sh
I get output:
d1 is loaded
So it looks like d1.sh script is loading, but d2.sh not. My question is, why is this happening and how should I do it to load all scripts stored in ./deep folder?
Try this,
#!/bin/bash
for file in ./deep/*;
do
source $file;
done

Bash: getting error in test "[[ not recognized" [duplicate]

This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 2 years ago.
The community is reviewing whether to reopen this question as of yesterday.
I'm working with a bash script that is currently working on a server (RHEL4). I'm developing on my laptop with Ubuntu 10.04, but I don't think the platform is causing the problem.
Here's what's happening:
I have a skeleton script that calls another script that does most of the work. However, it makes calls to getConfig.sh a lot. getConfig.sh basically just parses some command line argument (using getopts) and calls a Java program to parse some XML files. Anyways, getConfig.sh is throwing up lots of errors (but still seems to work).
Here's the message that I'm getting
getconfig.sh: 89: [[: not found
getconfig.sh: 89: [[: not found
getconfig.sh: 94: [[: not found
I get those three errors every time it runs; however, the script completes and the Java code runs.
Here's the relavent code section
parseOptions $*
if [[ "${debugMode}" == "true" ]] ; then
DEBUG="-DDEBUG=true"
echo "${JAVA_HOME}/bin/java ${DEBUG} -Djava.endorsed.dirs=${JAXP_HOME} -jar $(dirname $0)/GetXPath.jar ${XML_File} ${XPath_Query}"
fi
Line 89 is "parseOptions $* and line 94 is "fi"
Thanks for the answers.
If your script is executable and you are executing it like ./getconfig.sh, the first line of your script needs to be:
#!/bin/bash
Without that shebang line, your script will be interpreted by sh which doesn't understand [[ in if statements.
Otherwise, you should run your script like bash getconfig.sh, not sh getconfig.sh. Even if your default shell is bash, scripts run with sh will use a reduced set of bash's features, in order to be more compliant with the POSIX standard. [[ is one of the features that is disabled.
Use:
bash scriptname.sh
instead of:
sh scriptname.sh
If you are checking for equality, shouldn't the if be ?
if [[ "${debugMode}" = "true" ]]; then
....
fi

Shell script hangs when i switch to bash - Linux [duplicate]

This question already has answers here:
Pass commands as input to another command (su, ssh, sh, etc)
(3 answers)
Closed 6 years ago.
I'm very very new to Linux(coming from windows) and trying to write a script that i can hopefully execute over multiple systems. I tried to use Python for this but fount it hard too. Here is what i have so far:
cd /bin
bash
source compilervars.sh intel64
cd ~
exit #exit bash
file= "~/a.out"
if[! -f "$file"]
then
icc code.c
fi
#run some commands here...
The script hangs in the second line (bash). I'm not sure how to fix that or if I'm doing it wrong. Please advice.
Also, any tips of how to run this script over multiple systems on the same network?
Thanks a lot.
What I believe you'd want to do:
#!/bin/bash
source /bin/compilervars.sh intel64
file="$HOME/a.out"
if [ ! -f "$file" ]; then
icc code.c
fi
You would put this in a file and make it executable with chmod +x myscript. Then you would run it with ./myscript. Alternatively, you could just run it with bash myscript.
Your script makes little sense. The second line will open a new bash session, but it will just sit there until you exit it. Also, changing directories back and forth is very seldom required. To execute a single command in another directory, one usually does
( cd /other/place && mycommand )
The ( ... ) tells the shell that you'd like to do this in a sub-shell. The cd happens within that sub-shell and you don't have to cd back after it's done. If the cd fails, the command will not be run.
For example: You might want to make sure you're in $HOME when you compile the code:
if [ ! -f "$file" ]; then
( cd $HOME && icc code.c )
fi
... or even pick out the directory name from the variable file and use that:
if [ -f "$file" ]; then
( cd $(dirname "$file") && icc code.c )
fi
Assigning to a variable needs to happen as I wrote it, without spaces around the =.
Likewise, there needs to be spaces after if and inside [ ... ] as I wrote it above.
I also tend to use $HOME rather than ~ in scripts as it's more descriptive.
A shell script isn't a record of key strokes which are typed into a terminal. If you write a script like this:
command1
bash
command2
it does not mean that the script will switch to bash, and then execute command2 in the different shell. It means that bash will be run. If there is a controlling terminal, that bash will show you a prompt and wait for a command to be typed in. You will have to type exit to quit that bash. Only then will the original script then continue with command2.
There is no way to switch a script to a different shell halfway through. There are ways to simulate this. A script can re-execute itself using a different shell. In order to do that, the script has to contain logic to detect that it is being re-executed, so that it can prevent re-executing itself again, and to skip some code that shouldn't be run twice.
In this script, I implemented such a re-execution hack. It consists of these lines:
#
# The #!/bin/sh might be some legacy piece of crap,
# not even up to 1990 POSIX.2 spec. So the first step
# is to look for a better shell in some known places
# and re-execute ourselves with that interpreter.
#
if test x$txr_shell = x ; then
for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do
if test -x $shell ; then
txr_shell=$shell
break
fi
done
if test x$txr_shell = x ; then
echo "No known POSIX shell found: falling back on /bin/sh, which may not work"
txr_shell=/bin/sh
fi
export txr_shell
exec $txr_shell $0 ${#+"$#"}
fi
The txr_shell variable (not a standard variable, my invention) is how this logic detects that it's been re-executed. If the variable doesn't exist then this is the original execution. When we re-execute we export txr_shell so the re-executed instance will then have this environment variable.
The variable also holds the path to the shell; that is used later in the script; it is passed through to a Makefile as the SHELL variable, so that make build recipes use that same shell. In the above logic, the contents of txr_shell don't matter; it's used as Boolean: either it exists or it doesn't.
The programming style in the above code snippet is deliberately coded to work on very old shells. That is why test x$txr_shell = x is used instead of the modern syntax [ -z "$txr_shell" ], and why ${#+"$#"} is used instead of just "$#".
This style is no longer used after this point in the script, because the
rest of the script runs in some good, reasonably modern shell thanks to the re-execution trick.

Resources