[newbie] How to replace #!/usr/bin/env python3 with #!/usr/bin/ python3

Den0st

New Member
Joined
Sep 10, 2019
Messages
1
Reaction score
0
Credits
0
(If you don't feel like reading so much text I've bolded my actual question at the end of this thread)
(btw. Sorry for the - probably - weird gramatical context sometimes, Dutch is my mother language, English isn't)

Hi all, I'm new here in this forum & the title of my issue is just a small part of a 'big thing', at least - in my opinion.
But I'm someone who isn't experienced with Linux at all. Less than 2 weeks ago I installed a virtualbox on my Windows-laptop, and in there I'm running Ubuntu18.04 for a project at school-purpose.

I'll try to explain the "bit picture" of my problem so you guys have an idea what I actually want to do:
The very first step in the project that I have is to make an automatic conversion from a big bunch of Word-documents in .doc format (so not .docx! which seems to make a big difference). I mainly need to work in python and my teacher told me about the unoconv-script (https://github.com/unoconv/unoconv). 2 weeks ago I had no clue about how to work in terminal in linux. I watched a big amouont of YouTube tutorials and that way I learned a lot but I'm still getting used to it and there are some things that I still don't understand.

There are many issues that can come up while trying to get unoconv to work in Ubuntu18.04 and after a week of trying to figure it out it still doesn't work for me and I'm really wasting a lot of my time in this way + getting annoyed from it as well, but i have no choice, I need to figure out how I can make this work. Not 100% sure if this is the right forum or subsection from the forum for this (I'm sorry for that) but well... I'll see...
(I'm also not familiar with working with github yet, and neither other Python/linux/natural language processing related forums, this is the first one where I'm posting my problem.)

So... my problem: exactly like in this github-thread: https://github.com/unoconv/unoconv/issues/49 I'm having this issue:

4370


Using this github thread and some others I've been trying to solve the problem but from this link i only used the last 2 responses. I tried to change the UNOPATH just like Regebro told in there but that didn't solve my problem. Stas00 found his fix for Ubuntu 18.04 here: https://github.com/unoconv/unoconv/issues/405#issuecomment-352429704

One of the responses there is:
1) Try to copy from /usr/bin/unoconv to /usr/local/bin/unoconv.
2) And try to replace #!/usr/bin/env python3 on #!/usr/bin/python3 in unoconv file.
Number 1) I did, using the "cp" command but number 2)... These #!'s are confusing me. I googled it and found that it means "shebang" but what does it actually mean and how can I do this replacement exactly in the command line? I still don't really get it...

I'm hoping that after this I can get rid of this error with unoconv because well... I could've converted all the documents manually one-by-one in the time that I've spend to figure out about this issue. But I need to automate it, so it doesn't need to be done one by one.

This might be a very basic question but.. I'm new to Linux :/ and until now i didn't see this in any of the tutorials that i've seen...
 


Don't go moving, or messing with the script. That is not going to fix your problem. I think you're missing some dependencies that unoconv relies on. Instead remove whatever you have manually installed and install unoconv via apt instead. I think the problems are occurring because you are manually installing the script from github.

You said are using Ubuntu. I know that Unoconv is available as a package in the Debian repos. So it should also be in the Ubuntu repos.

You can verify this by using the command:
Code:
apt search unoconv --names-only

Whenever you want to install anything in Ubuntu - always use apt search to see if a pre-built package already exists for it. If there is a package in the repo's - installing that is always the easiest and best way to go. Only install from source, or from github as a last resort.

To install unoconv, you just need to run this:
Code:
sudo apt install unoconv

That will install unoconv plus any additional dependencies that you don't already have installed.

I don't use Ubuntu, I use Debian. But that just worked for me. It installed unoconv and a few dependencies that weren't already on my machine and unoconv works perfectly.

NOTE: From looking at the error messages in your screenshots - you may also need to ensure that libreoffice is installed.

I don't know if installing unoconv will automatically install libreoffice. I already had Libreoffice installed on my PC. So if libreoffice isn't installed on your Ubuntu VM - I'd install that too!
 
Last edited:
  • Like
Reactions: Rob
And in answer to your question about the shebangs.
They simply tell the shell which interpreter to use when executing a script. And the shebang MUST ALWAYS be the very first line of any script!

So if the shebang says:
#!/bin/bash it's a bash script
#!/usr/bin/python2 it's a python2 script
#!/usr/bin/python3 it's a python3 script
etc.

But you should also note that the above examples are hard-coded paths and NOT all distros are guaranteed to have things in exactly the same place.

Also, some users may have other preferences set up in their environment variables.

For example - a bash developer might have temporarily put a bleeding edge version of bash into their personal bin directory (/home/username/bin/) and might want to use that instead of the one installed on the system at /bin/ (or /usr/bin).

So when writing scripts that will be distributed and used on many different systems - instead of using hard-coded paths to interpreters, programmers will often use #!/usr/bin/env nameofinterpreter instead. Where nameofinterpreter is bash, or ruby, or python2, or python3, or perl, or lua, or brainfuck... or whatever interpreter should be used to run the script!

What env does is - it searches the directories listed in the users environment variables and finds the most appropriate version of the specified interpreter and then runs the script using it.

So there is absolutely nothing wrong with the unoconv script using /usr/bin/env python3 in it's shebang line.
env should search the users environment and use the first version of the python3 executable that it finds.

The order of the directories it will search in depends on how each users $PATH is set up, but typically it's something like this:
/home/username/bin/
/usr/local/bin/
/usr/bin/
/bin/

So it should search in users directories before the system ones.

Going back to the shebang line - regardless of whether you use a hard-coded path to an interpreter, or whether you use env to determine the path to an interpreter - the shebang is very useful because it leaves the system to load the interpreter each time the script is ran.

Without a shebang line, you'd have to manually invoke the appropriate interpreter using something like:
python3 myscript.py every time you wanted to run it.

Another thing to consider:
When you are writing a script that will be used as a system command, you don't typically want to have a file extension like .py, or .rb, or .php, or whatever at the end. You just want to use the name of the script as if it was a normal system command like cd or ls.

So instead of typing myscript.py, you'd want to be able to type myscript. To facilitate this you can simply name your script file myscript without the .py extension. So again, having a shebang at the start of your script - the system will know what type of script it is - even with the file-extension missing.

Now imagine you had a large collection of scripts, written in different languages - without shebangs AND without file extensions at the end.... You would need to remember the appropriate interpreter for each script/command - which would be highly impractical!

So instead of simply using:
command

You'd have to type:
interpreter command
Assuming you could remember which interpreter each command requires!

And then of course there are the commands like ls that are native executables that require no interpreter... So without the convenience that the shebang brings - you'd have to know a lot more about each command and whether it's a python script, or a ruby script, or a perl script, or a native executable etc.

If your scripts have shebangs - you can just install them somewhere in $PATH and use them as if they were native executables, or system commands.

Another thing to note - without a shebang and without manually invoking an interpreter - any script will just be treated as a series of ordinary shell commands - that will be executed in the currently running terminal... Which, depending on the scripting language used - could lead to unpredictable results and a lot of error messages!

So using the shebang makes using scripts a lot more convenient.
So unless your script is just a sequence of terminal/shell commands for the current terminal - ALWAYS use a shebang!

Using a shebang in our scripts we can:
1. Avoid having to manually invoke the interpreter each time we run any given script.
2. Avoid having to use file extensions at the end of our scripts (optional) - so we can invoke them as if they were any other system command, or a native executable.

Another thing you can do to allow scripts to be executed as if they were system commands - without having to type file extensions is to have a symbolic link called myscript that points to myscript.py (or .rb, or pl, etc).

The scripts should still use a shebang to specify the interpreter.

But typically, when this option is used, the symbolic link will be stored somewhere on the users $PATH and the script will be stored somewhere else that is off the path.

Quite a lot of detail there. I've tried to explain as simply and comprehensively as I can. If there is anything else I've forgotten, or glossed over, or got slightly incorrect - I'm sure that someone will chime in!

Likewise, if you have any other questions - fire away!
 
Last edited:
  • Like
Reactions: Rob


Top