Execute Command-Line Command from NSIS - nsis

I'm creating my first NSI script and I'm just wondering if I can execute a command-line command from NSIS or should I just execute a batch file? I don't really know where to begin and other similar topics have gone a little over my head.

I would recommend taking a look at the nsExec plugin. I just recently had a situation where I needed to ping a server from inside an NSIS script, and the following code worked perfectly for me.
nsExec::Exec '"C:\Windows\System32\PING.EXE" $URL'
The benefit of using nsExec is that it executes the command without making a dos box pop up on your screen. The return value is pushed onto the stack, and there are a couple different ways that you can access the output of the program as well (if any exists).
There isn't a whole lot of information about the plugin on the NSIS website that I could find, but the following link should get you started in the right direction:
http://nsis.sourceforge.net/Docs/nsExec/nsExec.txt
Edit:
I noticed you asked specifically about a COPY command which is an internal DOS command, meaning that you won't be able to execute it like I did with ping. I may be mistaken but you shouldn't need to use any outside programs to carry out basic commands like this. You should be able to replicate most of the internal commands using NSIS commands.
For Example to copy a file (or multiple files) use the NSIS command: CopyFiles
The NSIS Scripting Reference is your friend :) (So is ctrl+f)

Try using exec command http://nsis.sourceforge.net/Docs/Chapter4.html:
4.9.1.2 Exec
command
Execute the specified program and continue immediately. Note that the file specified must exist on the target system, not the compiling system. $OUTDIR is used for the working directory. The error flag is set if the process could not be launched. Note, if the command could have spaces, you should put it in quotes to delimit it from parameters. e.g.: Exec '"$INSTDIR\command.exe" parameters'. If you don't put it in quotes it will not work on Windows 9x with or without parameters.
Exec '"$INSTDIR\someprogram.exe"'
Exec '"$INSTDIR\someprogram.exe" some parameters'

We can launch a command-line command from NSIS, get the returned value and further develop the installation logic based on that.
Example: Let's say we need to get the installed clang compiler version. To get the version we have to launch:
clang --version
In NSIS we do this using ExecToStack:
nsExec::ExecToStack 'cmd /c "clang --version"'
Pop $0
Pop $0
;now we have the version in $0
Warning: Only the second Pop $0 gets the response that we want, in this case the clang version. The first Pop $0 grabs the exit code.

Related

Running Visual Studio Code from the CLI in Linux

I've downloaded and "installed" VSCode for Linux. I have placed the app in /home/Christian/Apps/VSCode/ and symlinked the executable to /usr/bin/code.
When I use this method to start Code it hijacks the terminal (expected I guess) and also dumps a lot of STDERR stuff at the same time.
If I redirect STDERR to a file, for example like
code 2> ~/.logs/VSCode-`date +%Y%m%d%H%M%S.log` &
Then I can get it to give me back my prompt, and it's silent (logging everything to the filename I gave it).
I was thinking of making this an alias, but then I realized I can't inject arguments ($1 $2 $3) in an alias. And I usually want to start code with code filename.js or code ..
What is the correct way to launch an application like this "in the background"?
Instead of making a symlink to the executable, create a bash script like this:
#!/bin/bash
/path/to/VSCode/Code "$#" 2>/dev/null &

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.

A sh line that scares me, is it portable?

I'm currently working on pm2, a process manager for NodeJS.
As it's targeted at Javascript, a new standard is coming, ES6.
To enable it on NodeJS I have to add the option --harmony.
Now for the bash part, I have to let the user pass this option to the interpreter that executes the file. By crawling the web (and found on Stackoverflow) I found this :
#!/bin/sh
':' //; exec "`command -v nodejs || command -v node`" $PM2_NODE_OPTIONS "$0" "$#"
bin line
Looks like a nice hack but is it portable enough ? On CentOS, FreeBSD...
It's kind of critical so I want to be sure.
Thank you
Let's break down the line of interest.
: is a do nothing in shells.
; is a command separator.
exec will replace the current process with the process of the command that it is executing.
Notice that in the exec command it passes "$0" and "$#" as parameter to the command?
This will allow the new process to read the script denoted by $0 and use it as a script input and reads the original parameters as well $#
The new process will read the input script from the beginning and ignore the comments like #!/bin/sh. and will also ignore :.
Here's the trick. Most interpreters, including perl, uses syntax that are ignored by shell or vice-versa so that on re-reading the input file, the interpreter will not exec itself again.
In this case, the new process ignored the whole line from :. The reason why the rest of the line is ignored? On some c like interpreters, // is a comment.
I forgot to answer your question. Yes it seems portable. There may be corner cases but I can't think of any right now.
To enable it on NodeJS I have to add the option --harmony.
Not necessarily. You can use normal "#!/usr/bin/env node" shebang, but set a harmony flags in runtime using setflags module.
I'm not sure it's better solution, but it's worth mentioning.

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

In my command-line, why does echo $0 return "-"?

When I type echo $0 I see -
I expect to see bash or some filename, what does it mean if I just get a "-"?
A hyphen in front of $0 means that this program is a login shell.
note: $0 does not always contain accurate path to the running executable as there is a way to override it when calling execve(2).
I get '-bash', a few weeks ago, I played with modifying a process name visible when you run ps or top/htop or echo $0. To answer you question directly, I don't think it means anything. Echo is a built-in function of bash, so when it checks the arguments list, bash is actually doing the checking, and seeing itself there.
Your intuition is correct, if you wrote echo $0 in a script file, and ran that, you would see the script's filename.
So based on one of your comments, you're really want to know how to determine what shell you're running; you assumed $0 was the solution, and asked about that, but as you've seen $0 won't reliably tell you what you need to know.
If you're running bash, then several unexported variables will be set, including $BASH_VERSION. If you're running tcsh, then the shell variables $tcsh and $version will be set. (Note that $version is an excessively generic name; I've run into problems where some system-wide startup script sets it and clobbers the tcsh-specific variable. But $tcsh should be reliable.)
The real problem, though, is that bash and tcsh syntax are mostly incompatible. It might be possible to write a script that can execute when invoked (via . or source) from either tcsh or bash, but it would be difficult and ugly.
The usual approach is to have separate setup files, one for each shell you use. For example, if you're running bash you might run
. ~/setup.bash
or
. ~/setup.sh
and if you're running tcsh you might run
source ~/setup.tcsh
or
source ~/setup.csh
The .sh or .csh versions refer to the ancestors of both shells; it makes sense to use those suffixes if you're not using any bash-specific or tcsh-specific features.
But that requires knowing which shell you're running.
You could probably set up an alias in your .cshrc, .tcshrc, or.login, and an alias or function in your.profile,.bash_profile, or.bashrc` that will invoke whichever script you need.
Or if you want to do the setup every time you login, or every time you start a new interactive shell, you can put the commands directly in the appropriate shell startup file(s). Of course the commands will be different for tcsh vs. bash.

Resources