schedule running a bash shell script in windows - windows

Apreciate any help and excuse me if my terminology is incorrect.
this is a script(*.sh file) that:
1-goes to a specific dir A
2-copies files from another dir B to dir A
3-#comented out# it also unzips the files in dir A and its subdirectories
4-#comented out# it also removes rows 1-6 and the last row of all *.csv files in dir A
#!/bin/bash
# Configure bash so the script will exit if a command fails.
set -e
#cd to the dir you want to copy to:
cd /cygdrive/c/path/I/want/to/copy/to
#echo Hello
#cp the files i want
#include the subdirectories
cp -r /cygdrive/c/path/I/want/to/copy/from/* .
# This will unzip all .zip files in all subdirectories under this one.
# -o is required to overwrite everything that is in there
#find -iname '*.zip' -execdir unzip -o {} \;
#find ./ -iname '*.csv' -exec sed -i '1,6d;$ d' '{}' ';'
Now I can get this script to work in cygwin by going to the dir where the file is stored and giving the following commands:
./filename.sh
or
/cygdrive/c/path/where/the/file/is/filename.sh
or
bash filename.sh
I can also do this in CMD/Windows DOS by doing the following:
C:\cygwin\bin\bash.exe -l
to get into a bash terminal and then give the following command:
/cygdrive/c/path/where/the/file/is/filename.sh
In task scheduler(in Windows) I have tried to schedule the following:
C:\cygwin\bin\bash.exe -l /cygdrive/c/path/where/the/file/is/filename.sh
but this does not work, even though the seperate commands work in CMD/Windows DOS as I have said above
Now what I want to do is be able to schedule this script(filename.sh) like I would a .vbs or .bat file in windows using task scheduler? Can anyone advise on this?
Note I have tried to write a Windows batch file(.bat) to do this(see below), but I could not get my unzip and sed commands to work,see here. So I have tried to write the Bash shell script above.
chdir C:\pointA
C:\cygwin\bin\cp.exe /cygdrive/v/pointB/* .
::find -iname *.zip -execdir unzip {} \;
::find ./ -iname '*.csv' -exec sed -i '1,6d;$ d' '{}' ';'

A solution is to associate .sh files with a batch file that runs bash. That way whenever you tell windows to execute an sh file it'll use the correct launcher - whether that's via a double click or a scheduled task. Here's mine:
#echo off
d:
chdir d:\cygwin\bin
bash --login %*
Associating a file type means that when you try to execute a file of that type, windows will use the path to that file as an argument passed to the program you've specified. For example, I have LibreOffice4 associated with .ods files. So if I doubleclick a .ods file, or just enter the path to a .ods file at the command prompt, windows will run open office calc, with the first parameter being the ods file. So if I have Untitled.ods on my desktop. I doubleclick it. That's effectively the same as opening up command prompt, typing
D:\Program Files (x86)\LibreOffice 4\program\scalc.exe" "C:\Users\Adam\Desktop\Untitled.ods".
and hitting enter. Indeed, if I do it, the expected happens: open office calc starts up and loads the file.
You can see how this works if you change the association to echo.exe (which I found in D:\cygwin\bin).
If I change the association to echo, open up the command prompt and type
"C:\Users\Adam\Desktop\Untitled.ods"
I'll just see echo.exe echo the filename back to me.
So what I'm suggesting you do is this:
create a batch file to run bash scripts using cygwin's bash (or use mine).
change the association for .sh files to that batch file
execute those .sh files directly, as though they were .exe or .bat files.

why not creating a batchfile (.bat) that loads your cygwin bashscript and schedule this batchfile? like this you dont have to deal with the way M$ handles paramters

Related

What is good way to move a directory and then run a command to the file inside it using a bash shell one-liner

I would like to find txt files with find command and move the directory of the found file, and then apply a command to the file using a bash shell one-liner
For example, this command works, but the acmd is executed in the current directory.
$ find . -name "*.txt" | xargs acmd
I would like to run acmd in the txt file's direcotry.
Does anyone have good idea?
From the find man page:--
-execdir command ;
-execdir command {} +
Like -exec, but the specified command is run from the subdirec‐
tory containing the matched file, which is not normally the
directory in which you started find. This a much more secure
method for invoking commands, as it avoids race conditions dur‐
ing resolution of the paths to the matched files. As with the
-exec action, the `+' form of -execdir will build a command line
to process more than one matched file, but any given invocation
of command will only list files that exist in the same subdirec‐
tory. If you use this option, you must ensure that your $PATH
environment variable does not reference `.'; otherwise, an
attacker can run any commands they like by leaving an appropri‐
ately-named file in a directory in which you will run -execdir.
The same applies to having entries in $PATH which are empty or
which are not absolute directory names. If find encounters an
error, this can sometimes cause an immediate exit, so some pend‐
ing commands may not be run at all. The result of the action
depends on whether the + or the ; variant is being used;
-execdir command {} + always returns true, while -execdir com‐
mand {} ; returns true only if command returns 0.
Just for completeness, the other option would be to do:
$ find . -name \*.txt | xargs -i sh -c 'echo "for file $(basename {}), the directory is $(dirname '{}')"'
for file schedutil.txt, the directory is ./Documentation/scheduler
for file devices.txt, the directory is ./Documentation/admin-guide
for file kernel-parameters.txt, the directory is ./Documentation/admin-guide
for file gdbmacros.txt, the directory is ./Documentation/admin-guide/kdump
...
i.e. have xargs "defer to a shell". In usecases where -execdir suffices, go for it.

shell script to disassemble object files?

I have never in my life made a shell script (although I have had to find and delete multiple troll ones my friends put on my school account when i am not looking).
I have some .o files under the working directory. I want a shell script that, by being given a simple (no path) .o file name, finds the matching file under the current directory and then runs the shell command
arm-none-eabi-objdump -D <found file>
So if I give it example.o, it will find dir1/dir2/example.o and then run
arm-none-eabi-objdump -D dir1/dir2/example.o
A shell script isn't especially needed for this, but I will attempt to cover all approaches. This assumes that the shell of choice is bash, but this may work for other shells as well. First, you need to consider whether you may have multiple object files with the same name, and what you may want to do if you do. If you want to dump only the first match, then this should work for you:
find ./ -name example.o -exec arm-none-eabi-objdump -D '{}' \; -quit
If, however, you want to dump all found matches, you can either remove the -quit (which will concatenate the output) or put the command in a loop:
find ./ -name example.o |
while read file; do
arm-none-eabi-objdump -D "$file" | less
done
If you wish to save yourself the typing (or reverse search) and put this in a shell script, all you need to do is put the same text in a file, add at the beginning of the file #!/bin/bash on its own line, and then make the file executable via chmod a+rx my-script.sh. Then you can run the script by typing ./my-script.sh example.o (assuming you are in the same directory as the script). Note that unless you put the script somewhere in your PATH environment variable, then you do need the ./ before the file name.

List md5sum of files on a remote server using ssh and return the output in text file?

I have Machine-A and Machine-B and both are Ubuntu servers. Now I want to list all the files on Machine-B using ssh. I want to return the result in a text file so I can analyse the result and the use scp to copy the required files.
ssh my_user_name#192.168.150.4 'bash -s tree /f'
ssh my_user_name#192.168.150.4 'bash -s ls -LR'
Now this command is not giving the result I wanted. Can anyone help with this so I can list all files on the remote computer using ssh and return the output in the form of a text file.
I am using ls -LR to list files and SSH to remote script execution.
From the Answer i worked on my problem and iam updating the question to match one little requirement.
I got the list of files throught this command ssh my_user_name#192.168.150.4 ls /something/sub > output.txt
But i want the md5sum of all files instead of names because 2 file names might get match.So is there any way to list all files and return all md5sum of all files and return to output.txt file.
Copy the file list to a valid path in Machine B and copy it back to Machine A using scp
ssh username#machineB 'ls -LR /path/to/dir > ~/fileList'
To return the md5sum of all the files in the directory, use find as
ssh username#machineB 'find /path/to/dir -type f -exec md5sum {} \; > ~/md5sum_fileList'
Now copy the file back to machine A, using a glob pattern to copy the files having the pattern fileList
scp username#machineB:~/*fileList* username#machineA:~/
All you need to do is specify the command, without using "bash". Your default shell will be used on the remote device to execute the command.
ssh remote-host command
To save the output of your ls command to a file, you can simply use the usual shell redirection:
ssh remote-host command > output.txt
Just in case you end up with multiple file names on a single line, you may need to use -1 on the ls command line. Also, remember that if a filename includes a space, you need quotes in a shell script to support those...
To run multiple commands in a row, although the output won't be as easy to manage, you use quotes and separate commands with semicolons (for example) as in:
ssh remote-host "command1; command2; command3" > output.txt
In regard to md5sum, you can run that against all the files in a directory using the find command along with md5sum:
ssh remote-host "find . -type f -exec md5sum {} \;" > output.txt
Change the path (. in the example) to whatever works for you.

running 2 unix commands in the same line in a batch file

Apreciate any help and excuse me if my terminology is incorrect.
What I am trying to do is write a scrpit/.bat file that will do the following:
copy 1 directory(and subdirectories) from pointA, to point B.
Then in pointB(and subdirectories) unzip the files which will give *.csv files
Then in pointB(and subdirectories) I want to delete some rows from all these csv files
This unix command, run on cygwin, will copy all the files from /cygdrive/v/pointA/* to the current directory . (i.e. the dot is the current working directory)
cp /cygdrive/v/pointA/* .
This unix command, run on cygwin, will go through all the files in the directory and subdirectories that end with .zip
and unzip them
find -iname *.zip -execdir unzip {} \;
This unix command, run on cygwin, will go through all the files in the directory and subdirectories that end with .csv
For each file it deletes the 1st 6 rows and the last row and that's the returned file.
find ./ -iname '*.csv' -exec sed -i '1,6d;$ d' '{}' ';'
I was looking to do this in one script/bat file but I am having trouble with the first find command
I am having trouble with the find and unzip commands on the one line and am wondering how and if this can be done
chdir C:\pointA
C:\cygwin\bin\cp.exe /cygdrive/v/pointB/* .
::find -iname *.zip -execdir unzip {} \;
::find ./ -iname '*.csv' -exec sed -i '1,6d;$ d' '{}' ';'
I did try something like this:
C:\cygwin\bin\find.exe -iname *.zip -execdir C:\cygwin\bin\unzip.exe {} \;
but I get the following:
/usr/bin/find: missing argument to `-execdir'
Can anyone advise if/how this can be done?
The Cygwin tools use their own kind of paths, e.g. /cygdrive/c/cygwin/bin/unzip.exe though sometimes the Windows paths with backslashes work, the backslashes do tend to confuse the Cygwin tools.
I highly recommend you write your tool in Bash shell script instead of a cmd.exe Windows batch file. In my experience (1) it's much easier to do flow control in bash scripts than in batch files, and (2) the Cygwin environment works better from Bash. You can open a bash shell and run bash yourscript.sh.
Your Bash script might look something like this: (untested)
#!/bin/bash
# This script would be run from a Cygwin Bash shell.
# You can use the Mintty program or run C:\cygwin\bin\bash --login
# to start a bash shell from Windows Command Prompt.
# Configure bash so the script will exit if a command fails.
set -e
cd /cygdrive/c/pointA
cp /cygdrive/v/pointB/* .
# I did try something like this:
# 1. Make sure you quote wildcards so the shell doesn't expand them
# before passing them to the 'find' program.
#
# 2. If you start bash with the --login option, the PATH will be
# configured so that C:\cygwin\bin is in your PATH, and you can
# just call 'find', 'cp' etc. without specifying full path to it.
# This will unzip all .zip files in all subdirectories under this one.
find -iname '*.zip' -execdir unzip {} \;

Finding differences between tarred folder and ordinary folder

I want to find the differences between tar folder and an ordinary folder. So I used "tar d folder2.tar folder" command in UNIX command line, but i didn't get any output. I couldn't even get the bash command prompt. How do i use "tar -d" command to find the differences between a tarred folder and an ordinary folder having files?
It's tar df folder2.tar folder. You have to add the f flag so it doesn't try to read the tar from stdin.

Resources