The Problem
I'm a little new to Cygwin and I'm trying to run a shell script in Cygwin from Batch and get the return value. I've been searching around, and I tried using C:\cygwin[64]\bin\bash[64].exe and even messing with C:\cygwin[64]\Cygwin.bat but to no avail.
Basically, I just want to be able to, from batch, interact with bash (from Cygwin). Please excuse me if this seems trivial to you, as I am rather new to Cygwin. Anyways, I have yet to find a working online solution.
Example Sudo Code:
cygwin-magic "echo shell-command"
#=> shell-command
Some Stuff I've Tried
I found all of these things from a lengthy Google hunt. Nothing did what I wanted it to.
"C:\cygwin[64]\bin\base[64].exe" /cygdrive/c/users/<me>/desktop/tmp.sh
#=> ZWNobyAiaGVsbG8i
"C:\cygwin[64]\bin\base[64].exe" -d /cygdrive/c/users/<me>/desktop/tmp.sh
#=> y▒h/usr/bin/base[64]: invalid input
"C:\cygwin[64]\bin\base[64].exe" -d -i /cygdrive/c/users/<me>/desktop/tmp.sh
#=> y▒h▒▒e/usr/bin/base[64]: invalid input
"C:\cygwin[64]\bin\base[64].exe" -d -i "echo hello"
#=> /usr/bin/base[64]: echo hello: No such file or directory
# I kind of gave up on all of my other attempts and tried this because why not? Surprise surprise, it didn't work (not that I expected it to).
"C:\cygwin[64]\Cygwin.bat"
echo "hello"
Contents of tmp.sh
Simply,
echo "hello"
Purpose
The reason I want to do this from batch is that I want to interact with bash from another language through batch (on Windows). I've got my solution planned out in that third language, but it's just the batch-to-cygwin that's not working.
Notes
Windows 7 Home Premium x64
Cygwin x64
I wrote all 64s in the code as [64] because I know 32-bit builds don't use that.
If I missed something or my question's a little off (too broad, too specific, etc.), please comment and I'll change it.
Perhaps you meant "C:\cygwin[64]\bin\basH[64].exe" not "C:\cygwin[64]\bin\base[64].exe"
Related
I wrote a script with six if statements that looks like this:
#!/usr/bin/bash
if [ -n $var1 ]
then
for f in /path/*.fastq.gz
do
x=${f/%.fastq.gz/_sample1-forward.fastq.gz}
y=${f/%.fastq.gz/_sample1-forward.out}
q=${f/%.fastq.gz/_temp.fastq.gz}
command [options] -i $f -o $temp${x##*/}
cp $temp${x##*/} $temp${q##*/}
done
else
echo "no $var1"
for f in /path/*.fastq.gz
do
q=${f/%.fastq.gz/_temp.fastq.gz}
cp $f $temp${q##*/}
done
fi
The other five statements do a similar task for var2 to var6. When I run the script I get unexpected output (no errors no warnings), but when I copy paste each of the if statements to terminal I end up with the exact result I would expect. I've looked for hidden characters or syntax issues for hours now. Could this be a shell issue? Script written on OSX (default zsh) and execution on server (default bash). I have a feeling this issue is similar but I couldn't find an answer to my issue in the replies.
Any and all ideas are most welcome!
Niwatori
You should maybe look at the shebang. I think proper usage would be #!/usr/bin/env bash or #!/bin/bash.
thanks for the help, much appreciated. Shebang didn't seem to be the problem although thanks for pointing that out. Shellcheck.net reminded me to use
[[ ]]
for unquoted variables, but that didn't solve the problem either. Here's what went wrong and how I 'fixed' it:
for every variable the same command (tool) is used which relies on a support file (similar in format but different content). Originally, before every if statement I replaced the support file for the previous variable with the one needed for the current variable. For some reason (curious why, any thoughts are welcome) this didn't always happen correctly.
As a quick workaround I made six versions of the tool, all with a different support file and used PYTHONPATH=/path/to/version/:$PYTHONPATH before every if statement. Best practice would be to adapt the tool so it can use different support files or an option that deals with repetitive tasks but I don't have the time at the moment.
Have a nice day,
Niwatori
In cmd, it is possible to use Linux commands with the ubuntu or bash commands, but they are very fickle. In batch, it is also possible to make a VBScript-batch hybrid, which got me thinking, is it possible to make a Bash-batch hybrid? Besides being a tongue-twister, I feel that Bash-batch scripts may be really useful.
What I have tried so far
So far I tried using the empty bash and ubuntu commands alone since they switch the normal command-prompt to the Ubuntu/Bash shell, but even if you put commands after the ubuntu/bash they wouldn't show or do anything.
After I tried that, I tried using the ubuntu -run command, but like I said earlier, it’s really fickle and inconsistent on what things work and what things don't. It is less inconsistent when you pipe things into it, but it still usually doesn't work.
I looked here since it seemed like it would answer my question and I tried it, but it didn't work since it required another program (I think).
I also looked to this and I guess it failed miserably, but interesting concept.
What I've gotten from all of my research is that most people think when this is mentioned of a file that could be run either as a .bat file or as .sh shell file instead of my goal, to make a file that runs both batch and Bash commands in the same instance.
What I want this for relates to my other question where I am trying to hash a string instead of a file in cmd, and you could do it with a Bash command, but I would still like to keep the file as a batch file.
Sure you can use Bash in batch, assuming it is available. Just use the command bash -c 'cmd', where cmd is the command that you want to run in Bash.
The following batch line pipes the Hello to cat -A command that prints it including the invisible symbols:
echo Hello | bash -c "cat -A"
Compare the output with the result of the version completely written in Bash:
bash -c "echo Hello | cat -A"
They will slightly differ!
A formely working bash script no longer works after switching computers. I get the following error:
No such file or directory.
Before going on, please excuse any mistakes you may find since english is not my native language.
The script was used in cygwin under Windows XP. I now had to switch to cygwin64 under Windwos 7 (64bit).
The script is used as a checkhandler for the program SMSTools3 to split a file with a specific format into multiple smaller ones, which the program then uses to send SMS to multiple recipients. The script was copied directly from the page of SMSTools3 and uses the package formail.
After looking up the error the most likely problem was that the environmantle path was not set up to look in the right path (/usr/bin). I therefore added it to the path but to no avail.
I then deleted other entries in the enviromental path of windows which contained spaces because that could have been another explanation, but again to no avail.
Following is a minimal example of the code which produces the error.
#!/bin/bash
# Sample script to allow multiple recipients in one message file.
# Define this script as a checkhandler.
echo $PATH
which formail
outgoing="/var/spool/sms/outgoing"
recipients=`formail -zx "To:" < "$1"`
I added the lines the lines echo $Path and which formail to show if the script can find the correct file. Both results look fine, the second command gives me the right output '/usr/bin/formail'
But the line recipients=... throws me the error:
No such file or directory.
I do not have much experience with bash scripting, or cygwin in general. So if someone on this wonderful board could help me solve this problem, I would be really grateful. Thank you all for your help.
EDIT:
First of all thank you all for your comments.
Secondly, I would like to apologize for the late reply. The computer in question is also used for other purposes and my problem is part of a background routine, so I have to wait for "free time" on the pc to test things.
For the things #shellter pruposed: The ls command returned an error: '': No such file or directory.
The which -a formail as well as the echo $(which -a formail) commands that #DougHenderson pruposed returned the 'right' path of /usr/bin/formail. echo \$1 = $1 before the recipent line returned the path to the checkhandler file (/usr/local/bin/smsd_checkhandler.sh), the same command after the recipent line seems to show a empty string ($1 = ). Also, the pruposed change to the recipent line did not change the error.
For the dos2unix conversion that #DennisWilliamson pruposed, I opened the file in notepad++ to use their build in converion, but it showed me that the file is in unix format with Unix style line endings.
I'm running exercise 14 of Learn Ruby the Hard Way. If I run the script in cmd it works fine, but I've been using Cygwin because it's nicer. When I run it in cygwin using this command:
ruby ex14.rb Devon
I get the following output
test
one
two
Hi Devon, I'm the ex14.rb script.
I'd like to ask you a few questions.
Do you like me Devon?
> Where do you live Devon?
> What kind of computer do you have?
> Alright, so you said test about liking me.
You live in one. Not sure where that is.
And you have a two computer. Nice.
That is to say, the program starts and immediately runs the three STDIN.gets.chomp() commands, and once it gets through those it puts and prints everything at once.
Is there a way to fix this behaviour? I would obviously want to have the lines run in the order they are written. I was unsure what to google for this type of error - combinations of "cygwin", "ruby", "puts output delayed" and "gets out of order" returned nothing relevant. Those search terms seem to vague anyway.
What exactly is going on, and is there a solution?
I think it is all to do with the CR LF differences between dos and unix.
try this...
set -o igncr
before running your script.
There are a lot of tips (and warnings) on here for obfuscating various items within scripts.
I'm not trying to hide a password, I'm just wondering if I can obfuscate an actuall command within the script to defeat the casual user/grepper.
Background: We have a piece of software that helps manage machines within the environment. These machines are owned by the enterprise. The users sometimes get it in their heads that this computer is theirs and they don't want "The Man" looking over their shoulders.
I've developed a little something that will check to see if a certain process is running, and if not, clone it up and replace.
Again, the purpose of this is not to defeat anyone other than the casual user.
It was suggested that one could echo an octal value (the 'obfuscated' command) and use it as a variable within the script. e.g.:
strongBad=`echo "\0150\0157\0163\0164\0156\0141\0155\0145"`
I could then use $strongBad within the shell script to slyly call the commands that I wanted to call with arguments?
/bin/$strongBad -doThatThingYouDo -DoEEET
Is there any truth to this? So far it's worked via command line directly into shell (using the -e flag with echo) but not so much within the script. I'm getting unexpected output, perhaps the way I'm using it?
As a test, try this in the command line:
strongBad=`echo -e "\0167\0150\0157"`
And then
$strongBad
You should get the same output as "who".
EDIT
Upon further review, the addition of the path to the echo command in the variable is breaking it. Perhaps that's the source of my issue.
You can do a rotate 13 on any command you want hidden beforehand, then just have the the obfuscated command in the shell script.
This little bash script:
#!/bin/bash
function rot13 {
echo "$#" | tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]'
}
rot13 echo hello, world!
`rot13 rpub uryyb, jbeyq!`
Produces:
rpub uryyb, jbeyq!
hello, world!