The following simple script is apparently not so simple.
The entire script appears to work properly until I get to the npm command.
I have looked at the numerous threads here, but none of the solutions fix the issue.
Each of the scripts is kicked off by a parent script.
Here is the parent:
#!/bin/bash/
authGogglesPath='/c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles'
echo $'\nExecuting node commands for local running solution...\n'
#echo $(pwd)
# run the scripts
bash edge.sh ${edgePath} &
exec bash
I checked my path in the terminal and it's aware
I thought that it might be running as another associated profile so I tried the full path to npm, but the same results.
#!/bin/bash/
authGogglesPath='/c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles'
echo $'\nExecuting node commands for local running solution...\n'
#echo $(pwd)
# run the scripts
bash edge.sh ${edgePath} &
exec bash
That calls edge.sh with a string path for arg (more for later)
edge.sh is another simple script
#!/bin/bash/
PATH=$1
#echo $PATH
if [ -z "${PATH}" ] ; then
"PATH is empty! Aborting"
exit 1
fi
cd "${PATH}"
echo $'\nExecuting Edge...\n'
npm run dev
Each time I run this I'm receiving:
$ bash edge.sh /c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles/
Executing Edge...
edge.sh: line 13: npm: command not found
cmonroe#LP10-G6QD2X2 MINGW64 ~/cruxScripts
$
When in the terminal and manually navigating to the directory and running the command it works properly. Where the edge builds and starts.
Unless npm is in /c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles/, doing PATH=$1 means your PATH only refers to that one folder.
No more /usr/bin or any other folders your bash session might need.
As commented, adding to the PATH should work
PATH="$1:${PATH}"
For the last couple of hours I have been trying to start my startup.sh script on docker container start, but for some reason it doesn't work.
My Dockerfile to create the image:
FROM armv7/armhf-ubuntu:latest
MAINTAINER Mohammed Noureldin <m.n.e#hotmail.com>
RUN apt update && apt upgrade -y && apt install -y mumble-server
ADD scripts/startup.sh /startup.sh
My startup script:
#!/bin/bash
/etc/init.d/mumble-server start
Nothing happens here, though I tried to create a file inside the script but also nothing happened!
I tried to execute the script directly from command line, but it doesn't work I don't know why:
docker run command:
docker run --name murmur -itd --restart always --network bridge -p 64738:64738 -v /var/lib/mumble-server/ -v /etc/ mnoureldin/murmur:latest /bin/bash -c "bash /startup.sh;/bin/bash"
And here what I get when trying to execute the script manually:
43b9d8dd4116bc605537c7af35ab186ca165ea6e957fab5908d39b2f085edf41
mohammed#server01:~/Dockerfiles/Mumble $ docker attach murmur
root#43b9d8dd4116:/# bash
.dockerenv boot/ etc/ lib/ mnt/ proc/ run/ srv/ sys/ usr/
bin/ dev/ home/ media/ opt/ root/ sbin/ startup.sh tmp/ var/
root#43b9d8dd4116:/# bash startup.sh
Usage: /etc/init.d/mumble-server {start|stop|restart|force-reload}
Or when I have an empty line between the two lines of the script I get this error:
root#830193e67fd7:/# bash startup.sh
startup.sh: line 2: $'\r': command not found
Usage: /etc/init.d/mumble-server {start|stop|restart|force-reload}
Could some one explain what is heppening and why it doesn't work?
The error is caused by the line endings in your shell script. It looks like you're using Windows line endings (CRLF, or \r\n), where the unexpected r is confusing Bash. Bash only expects LF or \n, hence the error message.
Most programmer text editors have some kind of support for making these changes. Notepad++ has "Edit > EOL Conversion > Unix/OSX Format". Please see EOL conversion in notepad ++ for more info.
I have cygwin bash.sh file that contains the following:
bash.sh:
cd "data processing"
"data processing" at the same directory of bash.sh
I'm trying to run this bash file from cmd not cygwin for some reason.
First, I've updated the path environment variable with cygwin bin directory.
cmd command:
cd "<the-bash-file-directory>"
bash --login -c "bash '<the-bash-file-directory>\\bash.sh'"
then it gives me that error:
error
cd: data processing: No such file or directory
I'm a beginner in using cmd and cygwin and really stuck lots of the time at running things from each other and conflating paths!
Because bash.sh isn't being run from <the-bash-file-directory>. It's being run from your home directory. The --login switch is causing that to happen. You need to do something like this:
bash --login -c "cd <the-bash-file-directory> && ./bash.sh"
or get rid of the --login switch if you can:
cd "<the-bash-file-directory>"
bash -c "./bash.sh"
In order to use rsync I created a BASH script. It runs fine from the Cygwin shell in WIN 7 but fails when run from the WIN 7 Task Scheduler. My Task Scheduler Script is a simple:
c:\cygwin\bin\bash.exe -l -c "~user/rsync_Windows_Backup 2>&1 >> ~user/Documents_cron.log"
The initial directory is set to C:\Cygwin\bin.
My BASH script is a typical rsync command with [options] SRC DEST and some related housekeeping.
The rsync command within the "rsync_Windows_Backup" BASH script is:
/bin/time -f "\nElapse (hh:mm:ss.ss) %E" \
rsync.exe -v -rltz --chmod=a=rw,Da+x -u "$SRC" "$DEST" >> "$LOG" \
2 >> "$LOG"
$ ./rsync_Windows_Backup - succeeds.
But the Task Scheduler Job fails carping that it cannot find the DEST Folder that the BASH script references. When I do a "cd DEST" from the BASH command line the Folder is avialable and can be written to.
I should add some more details that the sender is a WIN 7 desktop that is mapped to a Vista desktop receiver with a drive mapping J:. The BASH script does start but fails with:
rsync: writefd_unbuffered failed to write 4 bytes to socket [sender]: Broken pipe (32)
rsync: mkdir "/cygdrive/J/DocumentsBackup" failed: No such file or directory (2) rsync error: error in file IO (code 11)
I have tried several ideas to influence how WIN 7 handles mappings and permissions assuming this is the root of the problem. So far nothing seems to help.
Another characteristic is that the exact same BASH script and Task Scheduler Job does succeed it WIN Vista Business Edition. So I am assuming there is something in WIN 7 that I am missing.
I am stumped and could use some guidance.
Thanks.
I now have this working in Win 7 from the task scheduler as I need. Thank you to #netubsi and #firerat of LinuxQuestionsorg and #konsolebox for the suggestions that lead to a solution.
Here is what I did:
cmd /c net use T: '\\server\share' # Created a separate temporary share for Cygwin
DEST="/cygdrive/T/User/FolderBackup/" # Use temporary Share in Destination
rsync -avuz --copy-links "$SRC" "$DEST" # Do backup
cmd /c net use T: /delete # Remove temporary share
It appears that in WIN 7 the share created in Windows is NOT available to a Cygwin script, IF it is launced from the Win 7 task scheduler. It IS available if the script is launced from the Cygwin command line. It also appears that this is NOT an issue in Win Vista.
This seems odd to me. Perhaps there is another explanation that I am missing. However I am just relieved to have this working!!
You can also just use the network address directly in cygwin:
DEST="//server/share/User/FolderBackup"
Cygwin mounts local and mapped drives under /cygdrive. Using taskscheduler in win7 if you list the contents of /cygdrive, all you will see are local drives???
First option is to run your script as
c:\cygwin\bin\bash.exe -l -c "~/rsync_Windows_Backup >> ~/Documents_cron.log 2>&1"
If you want to capture the stderr output as well, you have to place it in front to copy the fd of the file, and not of stdout.
Make sure that rsync_Windows_Backup has executable permissions. Running ls -l ~/rsync_Windows_Backup should show it.
If it doesn't work, try to use absolute paths. On your Cygwin screen where the current direcory shows ~ in the prompt type pwd which would show something like
User#System ~
$ pwd
/home/User
Basing from that as an example your command should now be like:
c:\cygwin\bin\bash.exe -l -c "/home/User/rsync_Windows_Backup >> /home/User/Documents_cron.log 2>&1"
I have a shell script which I want to run without using the "sh" or "bash" commands. For example:
Instead of: sh script.sh
I want to use: script.sh
How can I do this?
P.S. (i) I don't use shell script much and I tried reading about aliases, but I did not understand how to use them.
(ii) I also read about linking the script with another file in the PATH variables. I am using my university server and I don't have permissions to create a file in those locations.
Add a "shebang" at the top of your file:
#!/bin/bash
And make your file executable (chmod +x script.sh).
Finally, modify your path to add the directory where your script is located:
export PATH=$PATH:/appropriate/directory
(typically, you want $HOME/bin for storing your own scripts)
These are the prerequisites of directly using the script name:
Add the shebang line (#!/bin/bash) at the very top.
Use chmod u+x scriptname to make the script executable (where scriptname is the name of your script).
Place the script under /usr/local/bin folder.
Note: I suggest placing it under /usr/local/bin because most likely that path will be already added to your PATH variable.
Run the script using just its name, scriptname.
If you don't have access to /usr/local/bin then do the following:
Create a folder in your home directory and call it bin.
Do ls -lA on your home directory, to identify the start-up script your shell is using. It should be either .profile or .bashrc.
Once you have identified the start up script, add the following line:
PATH="$PATH:$HOME/bin"
Once added, source your start-up script or log out and log back in.
To source, put . followed by a space and then your start-up script name, e.g. . .profile or . .bashrc
Run the script using just its name, scriptname.
Just make sure it is executable, using chmod +x. By default, the current directory is not on your PATH, so you will need to execute it as ./script.sh - or otherwise reference it by a qualified path. Alternatively, if you truly need just script.sh, you would need to add it to your PATH. (You may not have access to modify the system path, but you can almost certainly modify the PATH of your own current environment.) This also assumes that your script starts with something like #!/bin/sh.
You could also still use an alias, which is not really related to shell scripting but just the shell, and is simple as:
alias script.sh='sh script.sh'
Which would allow you to use just simply script.sh (literally - this won't work for any other *.sh file) instead of sh script.sh.
In this example the file will be called myShell
First of all we will need to make this file we can just start off by typing the following:
sudo nano myShell
Notice we didn't put the .sh extension?
That's because when we run it from the terminal we will only need to type myShell in order to run our command!
Now, in nano the top line MUST be #!/bin/bash then you may leave a new line before continuing.
For demonstration I will add a basic Hello World! response
So, I type the following:
echo Hello World!
After that my example should look like this:
#!/bin/bash
echo Hello World!
Now save the file and then run this command:
chmod +x myShell
Now we have made the file executable we can move it to /usr/bin/ by using the following command:
sudo cp myShell /usr/bin/
Congrats! Our command is now done! In the terminal we can type myShell and it should say Hello World!
You have to enable the executable bit for the program.
chmod +x script.sh
Then you can use ./script.sh
You can add the folder to the PATH in your .bashrc file (located in your home directory).
Add this line to the end of the file:
export PATH=$PATH:/your/folder/here
You can type sudo install (name of script) /usr/local/bin/(what you want to type to execute said script)
ex: sudo install quickcommit.sh /usr/local/bin/quickcommit
enter password
now can run without .sh and in any directory
Add . (current directory) to your PATH variable.
You can do this by editing your .profile file.
put following line in your .profile file
PATH=$PATH:.
Just make sure to add Shebang (#!/bin/bash) line at the starting of your script and make the script executable(using chmod +x <File Name>).
Here is my backup script that will give you the idea and the automation:
Server: Ubuntu 16.04
PHP: 7.0
Apache2, Mysql etc...
# Make Shell Backup Script - Bash Backup Script
nano /home/user/bash/backupscript.sh
#!/bin/bash
# Backup All Start
mkdir /home/user/backup/$(date +"%Y-%m-%d")
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_rest.zip /etc -x "*apache2*" -x "*php*" -x "*mysql*"
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_apache2.zip /etc/apache2
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_php.zip /etc/php
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/etc_mysql.zip /etc/mysql
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/var_www_rest.zip /var/www -x "*html*"
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/var_www_html.zip /var/www/html
sudo zip -ry /home/user/backup/$(date +"%Y-%m-%d")/home_user.zip /home/user -x "*backup*"
# Backup All End
echo "Backup Completed Successfully!"
echo "Location: /home/user/backup/$(date +"%Y-%m-%d")"
chmod +x /home/user/bash/backupscript.sh
sudo ln -s /home/user/bash/backupscript.sh /usr/bin/backupscript
change /home/user to your user directory and type: backupscript anywhere on terminal to run the script! (assuming that /usr/bin is in your path)
Enter "#!/bin/sh" before script.
Then save it as script.sh for example.
copy it to $HOME/bin or $HOME/usr/bin
The directory can be different on different linux distros but they end with 'bin' and are in home directory
cd $HOME/bin or $HOME/usr/bin
Type chmod 700 script.sh
And you can run it just by typing run.sh on terminal.
If it not work, try chmod +x run.sh instead of chmod 700 run.sh
Make any file as executable
Let's say you have an executable file called migrate_linux_amd64 and you want to run this file as a command like "migrate"
First test the executable file from the file location:
[oracle#localhost]$ ./migrate.linux-amd64
Usage: migrate OPTIONS COMMAND [arg...]
migrate [ -version | -help ]
Options:
-source Location of the migrations (driver://url)
-path Shorthand for -source=file://path
-database Run migrations against this database (driver://url)
-prefetch N Number of migrations to load in advance before executing (default 10)
-lock-timeout N Allow N seconds to acquire database lock (default 15)
-verbose Print verbose logging
-version Print version
-help Print usage
Commands:
goto V Migrate to version V
up [N] Apply all or N up migrations
down [N] Apply all or N down migrations
drop Drop everyting inside database
force V Set version V but don't run migration (ignores dirty state)
version Print current migration version
Make sure you have execute privileges on the file
-rwxr-xr-x 1 oracle oinstall 7473971 May 18 2017 migrate.linux-amd64
if not, run chmod +x migrate.linux-amd64
Then copy your file to /usr/local/bin. This directory is owned by root, use sudo or switch to root and perform the following operation
sudo cp migrate.linux-amd64 /usr/local/bin
sudo chown oracle:oracle /user/local/bin/migrate.linux.amd64
Then create a symbolic link like below
sudo ln /usr/local/bin/migrate.linux.amd64 /usr/local/bin/migrate
sudo chown oracle:oracle /usr/local/bin/migrate
Finally add /usr/local/bin to your path or user profile
export PATH = $PATH:/usr/local/bin
Then run the command as "migrate"
[oracle#localhost]$ migrate
Usage: migrate OPTIONS COMMAND [arg...]
migrate [ -version | -help ]
Options:
-source Location of the migrations (driver://url)
-path Shorthand for -source=file://path
-database Run migrations against this database (driver://url)
-prefetch N Number of migrations to load in advance before executing (default 10)
-lock-timeout N Allow N seconds to acquire database lock (default 15)
-verbose Print verbose logging
-version Print version
-help Print usage
Commands:
goto V Migrate to version V
up [N] Apply all or N up migrations
down [N] Apply all or N down migrations
drop Drop everyting inside database
force V Set version V but don't run migration (ignores dirty state)
version Print current migration version
Make the script file as executable by using file's properties
Create alias for the executable in ~/.bashrc. alias <alias namme> = <full script file path>'
refresh the user session to apply it. source ~/.bashrc
Just to add to what everyone suggested. Even with those solutions, the problem will persist if the user wants to execute the script as sudo
example:
chmod a+x /tmp/myscript.sh
sudo ln -s /tmp/myscript.sh /usr/local/bin/myscript
typing myscript would work but typing sudo myscript would return command not found.
As sudo you would have to still type sudo sh myscript or sudo bash myscript.
I can't think of a solution around this.
Just:
/path/to/file/my_script.sh