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?
Related
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()
I have the following python file:
vagrant#vagrant-ubuntu-trusty-64:~/my_app$ cat version_py3.py
#!/usr/bin/env python3
print "Python 2 print statement"
and I thought python version_py3.py will enforce the use of python3. But the code ran fine. and python3 version_py3.py gives expected error.
vagrant#vagrant-ubuntu-trusty-64:~/my_app$ python3 version_py3.py
File "version_py3.py", line 3
print "Python 2 print statement"
^
Also, there is no /usr/bin/env folder on my linux. Am I missing something here with the shebang right, but Python 2 and Python 3 are both installed on my computer.
vagrant#vagrant-ubuntu-trusty-64:~/my_app$ python -V
Python 2.7.6
vagrant#vagrant-ubuntu-trusty-64:~/my_app$ python3 -V
Python 3.4.3
vagrant#vagrant-ubuntu-trusty-64:~/my_app$
When you execute a script and you want have the shebang line respected, you may not prepend "python" in the command. A binary executable as the head of a command, which could work in she-bang as well, any given she-bang is ignored because the command executable is always preferred by the kernel.
Example: So let's assume you have a little python script, but with cat in the shebang. What happens when you set the executable bit of the script and call it as the command head is that the system first reads the first line, strips off the initial two bytes and tries to execute the (mandatorily binary) executable and feed it the script file.
$ /tmp/getver
#!/bin/cat
import sys
print( sys.version )
And now try and see yourself prepending python, python2 and/or python3.
Trivia: The interpreter may choose to process the shebang another time, on its own. E.g. perl used to respect any flags like -w given, whether it is given on the shebang or on the command, no matter if perl is the command head.
Try to located the python installation with locate for example, and set it in your shebang, like #!/usr/bin/python3.6 . I bet it's here.
I am not sure if you have found the solution. In python3, the syntax for print is different. The message has to be inside the parenthesis.
Try print("Python 2 print statement")
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.
Yesterday I ran into the git execute bit bash script quirk - the one that requires:
git update-index --add --chmod=+x scriptname.sh
and it seemed strange to me that it was even possible to get stuck in this situation. (Ie having created a script file that you don't have permission to run).
If I have created a shell script - surely I can run it under the permissions of the shell execute permissions. Why would it need it's own execute permission bit?
My question is: Why does a bash script require an execute bit if a windows batch script can just be executed?
To run a script you have two options in unix like systems. First Option is to use a direct interpreter call with the script as parameter.
# run a bash script
bash test.sh
# run a python scripts
python test.py
The second option is mark your file as executable, with the execute bit and after a call like this ...
# sample bash
./test.sh
# sample python
./test.py
... your system tries to find the right interpreter for you. For this the first line 'shebang' of the script is used.
Bash example:
#!/bin/bash
# points to the installed bash interpreter - bash example
Python example:
#!/usr/bin/python
# points to the installed python interpreter
To your question windows only use the file extension to detect a executable file.
Well, Linux is not Windows. Linux/Unix file systems support the executable bit to distinguish executable from pure data files, and to control exec permissions for user|group|others. You can still run the script if you prefix it with the name of the shell/binary you want to start it with, but if you want to do ./scriptname.sh or execute it from the path it needs to be flagged as executable for you as the onwer|a group member|some other user, and for scripts usually the shebang in the first line that defines the interpreter to start the script with: #!/bin/bash.
I'm trying to build a software called Slicer3 on Windows 7 which features a "super build".
It's a All-in-one TCL Script to checkout and build Slicer3.
I ran CYGWIN and navigated til the correct directory, then ran the script and got:
$ ./Slicer3-svn/Scripts/getbuildtest.tcl
couldn't read file "./Slicer3-svn/Scripts/getbuildtest.tcl": no such file or directory
Obviously I am sure that the file exists and I gave it 777 permission. I'm running cygwin as admin.
The beginning of the tcl file's content is:
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$#"
So I tried commenting out line 3 and running directly
$ tclsh ./Slicer3-svn/Scripts/getbuildtest.tcl
but got the same error.
Any idea?
I will try to help troubleshooting as much as I can:
Determine if you have tclsh installed and it is in the PATH:
$ tclsh
Determine if tclsh works for a simple script:
$ echo puts hello > hello.tcl; tclsh hello.tcl
Determine if the script exists and readable:
$ cat ./Slicer3-svn/Scripts/getbuildtest.tcl
$ cd ./Slicer3-svn/Scripts
$ cat getbuildtest.tcl
As far as line-ending (DOS CRLF vs. Unix LF):
$ cd ./Slicer3-svn/Scripts
$ sed 's/\r\n/\n/g' getbuildtest.tcl > getbuildtest_new.tcl
$ tclsh getbuildtest_new.tcl
This way, we can narrow down the problem, should any of the steps failed.
Description: TCLSH couldn't read file: no such file or directory.
Possible reason: TCLSH under CYGWIN does not resolve windows PATH's properly, and cannot find the files.
Workaround: move the script within the CYGWIN path.
just moving the script to a "simpler" path works for me. I'm not that sure about the reason, neither how to solve this misbehaviour.