"mode" doesn't run in python 3.5 subprocess - python-3.x

I have encountered a bit of a conundrum while working on an automation project.
When I try to run:
program = subprocess.run("mode")
I get:
FileNotFoundError: [WinError 2] The system cannot find the file specified
However, when I replace mode with ipconfig:
program = subprocess.run("ipconfig")
it runs perfectly fine.
Anyone got an explanation? I am currently using a batch file to run the mode command, but I would like to change the arguments without editing a batch file.
Edit 1:
I also just tried using os.system:
os.system("mode")
and that also worked.
Edit 2:
Now I would just like answer to the original problem just to understand what was going on.

In Actual meaning of 'shell=True' in subprocess it pretty much says that shell=True is something that you should shy away from.
FileNotFoundError: [WinError 2] The system cannot find the file specified
Is what tipped me off that you might want shell=True in your subprocess call. If the file can't be found that means one of two things:
It's not on your path.
It's not actually a file.
For instance, in Linux:
$ which echo
echo: shell built-in command
That makes it pretty obvious that there is no echo file. It's just a command that's built into the shell. This may be the same thing when it comes to mode on Windows. Though this site seems to suggest that it's a MODE.COM file. You may try invoking that, as in
subprocess.run('MODE.COM')
That may work - at least according to one of the answers that I linked to
Invoking via the shell does allow you to expand environment variables and file globs according to the shell's usual mechanism. On POSIX systems, the shell expands file globs to a list of files. On Windows, a file glob (e.g., ".") is not expanded by the shell, anyway (but environment variables on a command line are expanded by cmd.exe).
So in your case, perhaps mode isn't a file, but MODE.COM is, and since Windows has a spotty relationship with casing, it seems possible that by passing shell=True, the Windows shell happily takes mode and converts it to MODE.COM for you, but without it, it tries to execute the file literally named mode, which doesn't exist.

Related

Linux shell to windows batch file

I have a Windows dedicated server and I installed Multicraft to run Minecraft servers, and I wanted to add a accept EULA button, since I did not know much about bat files, so I found a sh file online and I did not want to use Cygwin because I don't know how to install it and make it run properly.
I want to change this to a .bat file:
#!/bin/sh echo 'eula=true' > "$SERVER_DIR/eula.txt"
it basically finds the line eula=false in eula.txt and changes it to true from what i understand
I would guess that this is what you're looking for:
echo eula=true>>%SERVER_DIR%\eula.txt
Given the double greater-than symbol it should append the line to the indicated file. Note that we're using a backslash here. You might want to look at the contents of that SERVER_DIR environment variable to see if it will work on a Windows-based computer.
If you want to mirror the behavior in the UNIX script then use a single greater-than symbol to overwrite the file content.

What's a .sh file?

So I am not experienced in dealing with a plethora of file types, and I haven't been able to find much info on exactly what .sh files are. Here's what I'm trying to do:
I'm trying to download map data sets which are arranged in tiles that can be downloaded individually: http://daymet.ornl.gov/gridded
In order to download a range of tiles at once, they say to download their script, which eventually leads to daymet-nc-retrieval.sh: https://github.com/daymet/scripts/blob/master/Bash/daymet-nc-retrieval.sh
So, what exactly am I supposed to do with this code? The website doesn't provide further instructions, assuming users know what to do with it. I'm guessing you're supposed to paste the code in to some other unmentioned application for a browser (using Chrome or Firefox in this case)? It almost looks like something that could be pasted in to Firefox/Greasemonkey, but not quite. Just by a quick Google on the file type I haven't been able to get heads or tails on it.
I'm sure there's a simple explanation on what to do with these files out there, but it seems to be buried in plenty of posts where people are already assuming you know what to do with these files. Anyone willing to just simply say what needs to be done from square one after getting to the page with the code to actually implementing it? Thanks.
What is a file with extension .sh?
It is a Bourne shell script. They are used in many variations of UNIX-like operating systems. They have no "language" and are interpreted by your shell (interpreter of terminal commands) or if the first line is in the form
#!/path/to/interpreter
they will use that particular interpreter. Your file has the first line:
#!/bin/bash
and that means that it uses Bourne Again Shell, so called bash. It is for all practical purposes a replacement for good old sh.
Depending upon the interpreter you will have different languages in which the file is written.
Keep in mind, that in UNIX world, it is not the extension of the file that determines what the file is (see "How to execute a shell script" below).
If you come from the world of DOS/Windows, you will be familiar with files that have .bat or .cmd extensions (batch files). They are not similar in content, but are akin in design.
How to execute a shell script
Unlike some unsafe operating systems, *nix does not rely exclusively on extensions to determine what to do with a file. Permissions are also used. This means that if you attempt to run the shell script after downloading it, it will be the same as trying to "run" any text file. The ".sh" extension is there only for your convenience to recognize that file.
You will need to make the file executable. Let's assume that you have downloaded your file as file.sh, you can then run in your terminal:
chmod +x file.sh
chmod is a command for changing file's permissions, +x sets execute permissions (in this case for everybody) and finally you have your file name.
You can also do it in your GUI. Most of the time you can right click on the file and select properties; in XUbuntu the permissions options look like this:
If you do not wish to change the permissions, you can also force the shell to run the command. In the terminal you can run:
bash file.sh
The shell should be the same as in the first line of your script.
How safe is it?
You may find it weird that you must perform another task manually in order to execute a file. But this is partially because of a strong need for security.
Basically when you download and run a bash script, it is the same thing as somebody telling you "run all these commands in sequence on your computer, I promise that the results will be good and safe". Ask yourself if you trust the party that has supplied this file, ask yourself if you are sure that you have downloaded the file from the same place as you thought, maybe even have a glance inside to see if something looks out of place (although that requires that you know something about *nix commands and bash programming).
Unfortunately apart from the warning above I cannot give a step-by-step description of what you should do to prevent evil things from happening with your computer; so just keep in mind that any time you get and run an executable file from someone you're actually saying, "Sure, you can use my computer to do something".
If you open your second link in a browser you'll see the source code:
#!/bin/bash
# Script to download individual .nc files from the ORNL
# Daymet server at: http://daymet.ornl.gov
[...]
# For ranges use {start..end}
# for individul vaules, use: 1 2 3 4
for year in {2002..2003}
do
for tile in {1159..1160}
do wget --limit-rate=3m http://daymet.ornl.gov/thredds/fileServer/allcf/${year}/${tile}_${year}/vp.nc -O ${tile}_${year}_vp.nc
# An example using curl instead of wget
#do curl --limit-rate 3M -o ${tile}_${year}_vp.nc http://daymet.ornl.gov/thredds/fileServer/allcf/${year}/${tile}_${year}/vp.nc
done
done
So it's a bash script. Got Linux?
In any case, the script is nothing but a series of HTTP retrievals. Both wget and curl are available for most operating systems and almost all language have HTTP libraries so it's fairly trivial to rewrite in any other technology. There're also some Windows ports of bash itself (git includes one). Last but not least, Windows 10 now has native support for Linux binaries.
sh files are unix (linux) shell executables files, they are the equivalent (but much more powerful) of bat files on windows.
So you need to run it from a linux console, just typing its name the same you do with bat files on windows.
Typically a .sh file is a shell script which you can execute in a terminal. Specifically, the script you mentioned is a bash script, which you can see if you open the file and look in the first line of the file, which is called the shebang or magic line.
I know this is an old question and I probably won't help, but many Linux distributions(e.g., ubuntu) have a "Live cd/usb" function, so if you really need to run this script, you could try booting your computer into Linux. Just burn a .iso to a flash drive (here's how http://goo.gl/U1wLYA), start your computer with the drive plugged in, and press the F key for boot menu. If you choose "...USB...", you will boot into the OS you just put on the drive.
How do I run .sh scripts?
Give execute permission to your script:
chmod +x /path/to/yourscript.sh
And to run your script:
/path/to/yourscript.sh
Since . refers to the current directory: if yourscript.sh is in the current directory, you can simplify this to:
./yourscript.sh
or with GUI
https://askubuntu.com/questions/38661/how-do-i-run-sh-scripts/38666#38666
https://www.cyberciti.biz/faq/run-execute-sh-shell-script/
open the location in terminal then type these commands
1. chmod +x filename.sh
2. ./filename.sh
that's it

Strange "sh" behaviour

I am developing an application on Beaglebone board with Angstrom distrubition fo Linux.I faced an interesting problem.
When I execute :
sh /home/root/Desktop/BBTCP/out/vehicleDetect 192.168.10.29
in terminal it says
/home/root/Desktop/BBTCP/out/vehicleDetect: /home/root/Desktop/BBTCP/out/vehicleDetect: cannot execute binary file
But when i execute
cd /home/root/Desktop/BBTCP/
and
sh out/vehicleDetect 192.168.10.29
it starts working??
What is the reason and why I can't run tha application with first configuration?
I think it is about the difference between ./ and sh. What are the differences?
My first guess would be that one of the folders in the path /home/root/Desktop/BBTCP is a link. If vehicleDetect is a script and it invokes itself recursively, then this link might be confusing it.
If that's not the case, try sh -x /home/root/Desktop/BBTCP/out/vehicleDetect and see what that prints.
Lastly, check what's in the folder /home/root/Desktop/BBTCP. There might be an executable sh in there. If your path contains ., a different shell might be executed.
Seems like /home/root/Desktop/BBTCP/out/vehicleDetect is invoking a binary file (an executable) that was built on a different architecture.
The main difference between sh and ./ is that ./ will attempt to execute the file itself as an executable, whereas sh will do that for you. It could be that there is a weird magic number at the start of the file, but you would expect sh to complain about that.
Best guess though it is a #! line at the start of the file which either contains invalid characters or refers to a strange file. Did you, for example, bring this script file from another operating system (like Windows) that has different line endings? I have seen similar effects when text file scripts have not been converted but just copied. Maybe you downloaded it in a strange format?
Check with od -xc /home/root/Desktop/BBTCP/out/vehicleDetect and look at the first line.

Calling script from shell script - getting command not found

I am new to shell scripting. I am trying to work through this.
> script to execute in cron (util.sh)
#!/bin/sh
HOST='ahostname'
PORT='3306'
USER='auser'
PASS='apassword'
DB='adatabase'
. /mnt/stor/backups/backup.sh
(I also tried source /mnt/stor/backups/backup.sh)
> script to execute (backup.sh)
When backup.sh is called (it does get called) it appears to simply be parsed and not executed. So no matter what I put in it I get messages like:
/mnt/stor/backups/backup.sh: line 8: date: command not found
/mnt/stor/backups/backup.sh: line 8: mysqldump: command not found
/mnt/stor/backups/backup.sh: line 8: tar: command not found
/mnt/stor/backups/backup.sh: line 8: rm: command not found
The idea is to have a domain localized file, execute it with variables, and call a master script that uses the variable to do the dirty work. Because of limitations with one of my hosts and multiple domains this is the best method.
The script with the Problem seems to be /mnt/stor/backups/backup.sh. Try setting the PATH to include all the usual directories with binaries, so the script can find its tools. Or, even better, change /mnt/stor/backups/backup.sh and use absolute paths in the commands like /bin/rm instead of just 'rm'.
When running from cron, you can't rely on any variables that are normally in your login shell's profile (e.g.: PATH, CLASSPATH, etc). You have to set explicitly what you need. In your case, i'm guessing that it's the lack of a PATH variable that's causing your troubles.
It's also good practice to put full paths to the programs you're executing from an unattended script, just to make sure you really are going to run that specific command, i.e., don't rely on the path.
So instead of
date
for example, use
/bin/date
etc.

Setting up the default script interpreter in Apache on Linux

On Windows, the following registry setting configures the script interpreter to be used by Apache:
HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command=C:\Perl\bin\perl.exe
How is this done on Linux?
To add a bit more information to #Mohit's good answer:
Unix uses many interpreters for many languages. Some of them are called "shells", but most are just another computer language to the system. In fact, every file is written in some language, even if it's compiled assembly of Java bytecodes.
The first few bytes of a file are "magic": they tell the OS how to execute the file. If the first two bytes are '#!', the OS knows that the file needs an interpreter. The rest of the first line up to newline is then used as a command to execute. The first "word" (space-separated group of non-spaces) of the line is interpreted as absolute file name to run, and all the other words are passed to it as command line arguments. Last parameter is the file name of the file you're running.
So, for example, if you have the first line as
#!/bin/tclsh
in a file /home/user/aaa.tcl
the OS will execute /bin/tclsh with /home/user/aaa.tcl as command line argument:
/bin/tclsh /home/user/aaa.tcl
For a more advanced example, try this:
#! /bin/env perl
in /home/user/myperlscript
This executes the following command:
/bin/env perl /home/user/myperlscript
/bin/env is a utility program that looks up its first argument using PATH environment variable, and then executes the program it finds, passing the rest of its arguments on to the program. With the help of env, you can use PATH to find your interpreters.
If you are talking about CGI script handlers.
It is set on the first line of each CGI script, I frequently use TCL as my script handler in Apache and hence add:
#!/bin/tclsh
Add this line on top of your script, eg. test.cgi and it will be executed by TCL shell whenever it is requested by someone.
Similary you can set it as
for BASH -- #!/bin/sh
or
for PERL -- #!/usr/bin/perl
Note: The path for the shell binary executable can be different, from above, on your machine. Use the following command to find it:
#which perl
Also, as Max has suggested, do check if Apache is configured to allow CGI scripts
Find detailed description of the same here at this Apache Tutorial Link
ScriptInterpreterSource is an Apache configuration setting and is only supported on Windows. I'm not really experienced at configuring Apache on Linux but I reckon you should check out the Script directive.
There is no registry under Linux. Also, I doubt you will get Perl.exe running under Linux.

Resources