Loaded a script to /bin, then deleted, but still works - linux

I created a simple shell called glang then made it executable.
$ chmod +x glang
Then I copied it into /bin
$ sudo cp glang /bin
I made it work. However, then I wanted to delete it and went to /bin
$ cd /bin
Then delete it.
$ sudo rm glang
And when I listed files, I couldn't find the script, then I thought it's been deleted.
However, when I still write
$ glang
any where in the file system, the script still works!
Any idea whats going on?
Thanks in advance.
Content of glang is as follows(It's basically a preprocessor thing):
#!/bin/bash
echo $1 >> ~/lexer/var.cl
echo "\")" >> ~/lexer/var.cl
cat ~/lexer/var.cl >> ~/lexer/exe.cl
cat ~/lexer/char_processing.cl >> ~/lexer/exe.cl
cat ~/lexer/io_processing.cl >> ~/lexer/exe.cl
cat ~/lexer/lex_processing.cl >> ~/lexer/exe.cl
cat ~/lexer/main.cl >> ~/lexer/exe.cl
clisp ~/lexer/exe.cl

Try:
whereis <script name>

Under linux you should use /usr/local/bin for custom scripts that you create. That location is in the PATH and you can use your script from that location. So it's not a good idea to replace the "buildin" scripts. You can call the buildin script with:
buildin glang
If the scripts are installed over the package manager you can search with which or whereis. When you use the same name like the original one you can get problems. So you should give them another name.

Related

Directory structure variations in bash script

I have a shell script myautoappupgrade.sh where I automate a process of application upgrade. The script has to be run on few different servers. Unfortunately, the application is located in slightly different directory on each server - the number for parent directory varies between 1-20. How I can modify the script, so that the directory can be replaced by some sort of variable? I don't want to edit the script for each server because there are many directory queries in the automation script.
example:
cd /ae1/apps/myapp/upgradefiles/
unzip file.zip
./install.sh
the directory slightly changes on another server:
cd /ae2/apps/myapp/upgradefiles/
unzip file.zip
./install.sh
and another..
cd /ae3/apps/myapp/upgradefiles/
unzip file.zip
./install.sh
Try something like this:
#!/bin/bash
num=$1
cd /ae${num}/apps/myapp/upgradefiles/file.zip
unzip file.zip
./install.sh
Then call the script with the number as first argument:
myautoappupgrade.sh 1
The simple and obvious solution is to not hard-code the directory at all. Modify the script so it accepts the parent directory as an argument, or just cd into the parent directory before running the script.
Perhaps something like this:
while read server dir; do
ssh "$server" "cd '$dir' && unzip apps/myapp/upgradefiles/file.zip/file.zip && ./install.sh"
done <<\:
ernie /ae1
bert /ae2
cookiemonster /home/cmonster/anN
:
It would probably be even better if you unzipped into a temporary directory, but hopefully this should get you moving in the right direction.
Of course, if you can be sure that /ae[0-1] is always there and there is only one match,
cd /ae[0-9]/apps/myapp/upgradefiles/file.zip
would do what you are asking.
(Do you really have a file named file.zip inside a directory also named file.zip? I'm guessing actually take away the file.zip from the end of the cd path.)
By simply using:
cd /ae*/apps/myapp/upgradefiles/
The * will expand any character.

"No such file or directory" while in link path

When compiling, I always place the build in a separate directory. For example:
mkdir build
cd ./build
(cd ..; ./bootstrap)
../configure
make
Since I have plenty of RAM the aim is to compile on a TMPFS.
The script gets the name of the project, uses it for the name for the directory created in $XDG_RUNTIME_DIR/build and finally links it.
# setup-build.sh
#!/usr/bin/bash
set -e
my_project_name=$(basename $(pwd))
my_project_build_dir="$XDG_RUNTIME_DIR/build/$my_project_name"
mkdir -p $my_project_build_dir
ln -s "$my_project_build_dir" "$(pwd)/build"
The script runs without a problem. But, when I do cd ./build; ../configure it returns an error: bash: ../configure: No such file or directory. The file most certainly does exist, but Bash can't find it!
I altered the script to this:
#!/usr/bin/bash
set -e
my_project_src_dir="$(pwd)"
my_project_name="$(basename $(pwd))"
my_project_build_dir="$XDG_RUNTIME_DIR/build/$my_project_name"
mkdir -p "$my_project_build_dir"
ln -s "$my_project_build_dir" "$(pwd)/build"
cd "$my_project_build_dir"
echo "$my_project_src_dir" > "./project-src-dir.txt"
To compile I have to type cd ./build; $(cat ./project-src-dir.txt)/configure; make. This causes Bash complete to partial break, though. As in I can't TAB complete file names from $my_project_src_dir with this method, but TAB completion for arguments works fine. Ifautoconf is needed: (cd $(cat ./project-src-dir.txt); ./bootstrap). If anyone has any other ideas I would still prefer to be able to just do ../configure, although this will have to do for now.
Edit: Had to change my_project_name="$(basename '$my_project_src_dir') to my_project_name="$(basename $(pwd))" as it was taking '$my_project_src_dir' literally.

How to navigate to a single child directory without knowing its name using shell command?

I need to run a script in a remote machine from my JAVA code using runCommand() method. Now I can't always know the full path of the script as a particular directory name keeps changing. For example the path looks like this : /a/b/xxxxx/script . xxxx is the directory name that keeps changing and its the only single directory under /a/b/. Is there any shell command using which I can get the directory name ? I know using JAVA,but I specifically need shell command.
If there is only a single self-directory, another fool-proof way of doing it would be
cd */.
*/. is that this expands to the "self directory" (named .) in any subdirectory, which is of course the sub-directory itself. Refer the below example of how it works.
E.g.
$ pwd
/home/dude/
$ mkdir -p a/b/ldsnds/c
$ cd a/b/*/.
$ pwd
/home/dude/a/b/ldsnds
$ cd -
/home/dude/
$ cd a/b/*/./c
$ pwd
/home/dude/a/b/ldsnds/c
Below should give you the name of the directory in the directory "b".
$ find /a/b -type d -maxdepth 1 2> /dev/null
If you are so sure that it would always be one directory in /a/b then just store the output of find in a variable and move ahead.
Note: 2> /dev/null is just to get rid of errorneous warnings.

Move script.sh to bin

I'm new to shell programming and I'm trying to create a simple script that gives me some infos on the status of the machine (i.e date, time, users logged in etc) on Scientific Linux 6 (I know it's old, but the department of my university runs on it so there's no escaping)
Basically I've created my script "sysinfo.sh"
#!/bin/sh
....
exit 0
as root user I want to move it so that I can be able to execute it anywhere and I thought the right way to do it was
sudo mv sysinfo.sh usr/local/bin
but I get the error message
mv: cannot move `sysinfo.sh' to `usr/local/bin': No such file or directory
then I looked for the PATH and it gives me
$ echo $PATH
/u/geo2/sw//System/tools/bin:/usr/bin:/bin
What is the right place to move my script?
Best practice for these kind of manipulation or learning is to have scripts in your $HOME/bin directory.
mkdir $HOME/bin
export PATH=$PATH:$HOME/bin
mv sysinfo.sh $HOME/bin
chmod +x $HOME/bin/sysinfo.sh
If you anyway want to move it to /usr/local/bin, why not do that with:
sudo mv sysinfo.sh /usr/local/bin
chmod +x /usr/local/bin/sysinfo.sh
chmod command will make the script executable.
from chmod man:
x -- The execute/search bits.
The command that you posted indicates that you were trying to use the absolute path for copying, but you missed a leading slash --
the directory should be /usr instead of usr.
Try
sudo mv sysinfo.sh /usr/local/bin
Note that unless an absolute path is specified, the shell looks for the path relative to the current working directory.
In this case, the shell was looking for the subdirectory usr under the current directory which was not found;
hence the error message.
Thank you very much!
In the end, I didn't realize that the directory /usr/local/bin wasn't in the PATH
So i just needed to
export PATH=$PATH:/usr/local/bin
sudo mv sysinfo.sh /usr/local/bin
:D

linux/unix: script starting some command if some directory tree exists

I'm a linux newbie, so pardon me if you don't understand me :)
I have a problem that I need to run a command chmod 777 XXX (XXX is directory) but I cant login to it, but I can push UNIX script which will be executed to do this. But the problem is that I don't know in which path this script is started/placed :).
IN DETAIL: I need script which will check if relative path (directory tree) CCCC/YYY/XXX exists on this machine somewhere and if it exists following command needs to be started on this directory chmod 777 XXX. (XXX should be resolved to absolute path :))
I did some test with find, but no real result.
The locate command will help you here:
path_part=CCCC/YYY/XXX
if output=$( locate "$path_part" 2>/dev/null ); then
grep "$path_part$" <<< "$output" |
while IFS= read -r dir; do
# do something in "$dir"
done
fi
locate requires you to run updatedb -- your system may run it already periodically.

Resources