What is nim's equivalent of Python's `sys.executable`? - nim-lang

Following is the content of foo.py
import sys
print(sys.executable)
When I execute this, I can get the full path of the the Python interpreter that called this script.
$ /mingw64/bin/python3.9.exe foo.py
/mingw64/bin/python3.9.exe
How to do this in nim (nimscript)?

If you want to do that in Nim (not NimScript), you can take compiler executable path using https://nim-lang.org/docs/os.html#getCurrentCompilerExe
import os
echo getCurrentCompilerExe()

The question mentions NimScript, which has other uses in the Nim ecosystem, but can also be used to write executable scripts instead of using, e.g., Bash or Python. You can use the selfExe proc to get the path to the Nim executable which is running a NimScript script:
#!/usr/bin/env -S nim --hints:off
mode = ScriptMode.Silent
echo selfExe()
After saving the above as test.nims and using chmod +x to make the file executable, the script can be invoked to show the path to the current Nim executable:
$ ./test.nims
/home/.choosenim/toolchains/nim-1.4.8/bin/nim

Nim is compiled, so I assume you want to get the path of the application's own binary? If so, you can do that with:
import std/os
echo getAppFilename()

Related

Why using explicit interpreter in bash doesn't use path variable

Say I have a script /tmp/printy.py containing only:
#! /usr/bin/python2.7
print "hello world"
Why does this work:
chmod +x /tmp/printy.py
export PATH=$PATH:/tmp/
printy.py
But this doesn't:
chmod +x /tmp/printy.py
export PATH=$PATH:/tmp/
python printy.py
And what can be added to, say, a cron job which is supposed to run printy.py with a specific interpreter, to make it work?
Quite possibly duplicate but I can't find anything, maybe I'm using the wrong search terms?
Path lookups in the shell only apply to commands, not arbitrary files. In your first example, printy.py is the command name. In the second, it is just an argument to Python, and Python doesn't use PATH to find the script to run; it expects printy.py to be in the current working directory.
You can use a combination of PYTHONPATH and -m to simulate this:
PYTHONPATH=$PATH python -m printy

How to execute lua bytecode genrated by luac on linux

I have a simple lua source code called hello.lua
print('Hello Lua')
I complied this file to bytecode on a RedHat Linux machine , using Lua5.3.4 as follows:
luac -o hello.luac hello.lua
chmod +x hello.luac
./hello.luac
bash: ./hello.luac: cannot execute binary file
The architecture should be fine I guess. I cant figure what is wrong.
Precompiled Lua programs are run exactly the same way as source:
lua hello.luac
The shebang is removed by luac even if the lua source file has it. In some case when it's necessary to run the compiled binary without any parameter, e.g. CGI, you can add the shebang manually at the top of the luac file:
luac -o hello.luac hello.lua
echo '#!/usr/bin/env lua' > shebang
cat shebang hello.luac > hello.luac2
mv hello.luac2 hello.luac
chmod +x hello.luac
./hello.luac
As #lhf states in his answer Lua byte code is executed using the Lua interpreter, and as the manual suggests:
To allow the use of Lua as a script interpreter in Unix systems, the standalone interpreter skips the first line of a chunk if it starts with #. Therefore, Lua scripts can be made into executable programs by using chmod +x and the #! form.
Add a shebang as the first line of your script:
#!/usr/bin/env lua
print('Hello Lua')

Rename executable for single script in bash

I want to run shell script, where exe1 instead being looked up as /path/to/exe1 instead references what I see as exe2 in /path/to/exe2. Ideally, I want to do this in the most compact way with minimal side effects.
To make this example concrete, and somewhat similar to the problem I actually care about, I have a shell script script.sh where
$ cat script.sh
#!/usr/bin/env bash
python --version
I have two executables on my current PATH:
$ python --version
Python 2.7.x
$ python3 --version
Python 3.5.x
I want to call script.sh in such a way that
$ <magic> ./script.sh
Python 3.5.x
$ python --version
Python 2.7.x
The best solution I can find so far is
$ mkdir /tmp/python3 && ln -s $(which python3) /tmp/python3/python && env PATH="/tmp/python3:$PATH" ./script.sh
This could be made a little better by using mktemp -d and cleaning up, but it still involves writing mostly unnecessary files, for something it seems like I should just be able to tell bash, treat python as python3. Something like aliases would be ideal, but they don't get passed onto subshells. Is there an obvious tool I'm missing, or am I stuck with a variant of this method?
I want to call script.sh in such a way that
$ <magic> ./script.sh
Python 3.5.x
$ python --version
Python 2.7.x
You can do it like this using a function:
(python() { python3 "$#"; }; declare -xf python; ./script.sh)
We create a function called python inside a subshell that just invokes python3 executable.
Doing it in a sub-shell so that current environment is not messed up.

Why i can excute a newly created file which is not executable?

In Ubuntu, The default umask on Ubuntu is 022 which means that newly created files are readable by everyone, but only writable by the owner, nobody can excute it.
In this case, i create a new file :
touch test.rb # Its content is: puts "hello world"
ls -l demo.rb # -rw-r--r--
Then i excute test.rb :
ruby test.rb # output: "hello world"
Since the owner of the file does not have the "x" permission , then why I can successfully run the file ? or I have missed some knowledge about it ?
You are not executing the file as a binary. You are executing ruby binary with argument test.rb and it interprets the Ruby script. Therefore, only ruby binary needs execution privilage and not the script itself.
You can check the privileges of the binary by running stat (which ruby).
On the other hand if you place
#!/usr/bin/ruby
on the top of your script and make it executable with chmod a+x test.rb you could then make Linux run it. The binfmt module of the kernel will check search for #! (called shebang) in the file and run the interpreter for you.
You can find this shebang in lot of the shell scripts. Nowadays it is common to put #!/usr/bin/env ruby or #!/usr/bin/env python in order to use interpreter binary in other location that is available on PATH variable like /usr/local/bin/ruby. Again env is just another binary program. It will run its argument as a program. The kernel will pass script as the parameter which will result in command /usr/bin/env ruby test.rb.
Grzegorz Żur is right.
you can modify your test.rb like this:
#!/usr/bin/env ruby
puts 'hello world'
and then you excute it with .:
$ ./test.rb
you will see Permission denied.

Call rosrun from Matlab or alternative

I already have a ros package with an executable inside it. From the terminal this is what I do to execute it:
$ source ~/catkin_ws/devel/setup.bash
$ rosrun my_package my_executable
This executable print some text on the shell:
Hello world
I want to call this commands in Matlab and import the printed text. I tried creating a shell script like this:
#!/bin/bash
source ~/catkin_ws/devel/setup.bash
rosrun my_package my_executable
and running it from Matlab in the following way:
[a,b] = system('~/./my_script')
but this is what I get:
[rosrun] Couldn't find executable named my_executable below /home/user/catkin_ws/src/my_package
The script works fine if called directly from the shell. How can I solve?

Resources