The magic behind shebangs!

These are the notes I took to do my video about shebangs, which is available here: and here: Como shebangs funcionam - tiktokt video Unfortunately, all the videos are in portuguese. However, my notes are available bellow and the code is open source and available here: https://github.com/Dpbm/video-shebang. Enjoy :) Notes The name cames from Sharp-bang (#! from music sheet notation). Some say that it’s due to its phonetics (hash + bang). It especifies an interpreter for this script. Bash handles the shebang when the underlying system doesn’t do that. It’s usual to set it to #!/bin/bash to ensure that it will use Bash instead of any other shell. Now days it’s preferable to use #!/usr/bin/env bash to get bash from $PATH if installed in a different directory. The script fallback to its parent SHELL when no shebang is defined. The shebang is used for portability. When it’s not provided, the system raises an ENOEXEC (Exec Format error) error. file command uses the shebang, as well, to see which kind of executable is that. You don’t need a blank after #!. Also accepts relative paths. When a program runs in a unix-like system, it executes a kernel exec()(or any command from this family) function. It take a look at the first 16 bits, searching for a magic number that describes an executable. If it’s no signature is found it return an ENOEXEC error. As time went, this magic part of the file also described how to execute it. When the run starts running your script, it first tries to delegate it to the kernel, which search for the shebang and tries to execute the file with a different interpreter. If none was found, the bash itself tries to execute. Explicit calling a script via a shell command (like sh or bash) the shebang is ignored. Using /usr/bin/env doesn’t provide complete portability, but it’s a good practice. Arguments can be split differently in different systems, so it may break in some occasions. The path of the script is passed via argv to the interpreter. Calling trace execve -> do_execveat_common -> create a linux_binprm containing data from it (DEFINE_CLASS -> alloc_bprm ) -> bprm_execve -> exec_binprm -> search_binary_handler -> prepare_binprm -> kernel_read (read the file) -> it them iterates over a linked list of formats list_for_each_entry(fmt, &formats, lh) { the exec.c provides an external function `__register_binfmt` that is used by each type in `binfmt_*.c` to register in the lits, calling like: core_initcall(init_elf_binfmt); -> load_binary from struct linux_binprm if it's a script, it loads `binfmt_script.c` that has the method `load_script` which checks for the shebang -> open_exec (from exec.c) -> do_open_execat References https://unix.stackexchange.com/questions/149045/why-is-shebang-called-shebang https://www.gnu.org/software/bash/manual/bash.html#Shell-Scripts-1 https://medium.com/@jcroyoaun/a-deeper-view-into-the-shebang-for-linux-scripting-4a26395df49d https://stackoverflow.com/questions/3009192/how-does-the-shebang-work https://unix.stackexchange.com/questions/268766/what-exactly-happens-when-i-execute-a-file-in-my-shell https://crocidb.com/post/kernel-adventures/demystifying-the-shebang/ https://www.in-ulm.de/~mascheck/various/shebang/ http://www.faqs.org/faqs/unix-faq/faq/part3/section-16.html https://en.wikipedia.org/wiki/Shebang_(Unix) https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25 https://man7.org/linux/man-pages/man2/execve.2.html https://man7.org/linux/man-pages/man3/perror.3.html https://stackoverflow.com/questions/4689724/where-do-i-find-the-source-code-for-execve https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/exec.c#l1376 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/binfmts.h https://github.com/torvalds/linux/blob/master/fs/namei.c#L4849 https://docs.kernel.org/admin-guide/binfmt-misc.html https://github.com/torvalds/linux/blob/master/include/linux/list.h https://github.com/torvalds/linux/blob/master/fs/binfmt_script.c https://homepages.cwi.nl/~aeb/std/hashexclam.html https://www.oreilly.com/library/view/understanding-the-linux/0596005652/ch20s04.html

February 19, 2026 · 3 min · map[email:dpbm136@gmail.com name:Dpbm]

How does Python handle imports?

This is a topic that I discussed in the following youtube video (unfortunately only in brazilian portuguese) These notes were extracted from my github repo https://github.com/Dpbm/video-python-import-methods, take a look if you want more details and some code ;) Notes C includes headers (.h files) includes the interfaces for external code. including a header into a c source file is the same as copying the definition of the function or whatever to that context, but less prone to errors. #include it reads a file and places it inside the current source code. to avoid errors, use it to only import functions/declarations/definitions/etc from header files. includes using <> looks only in standard system directories. But without it, it first looks into the current path and then starts look for it in other system locations. Wrappers to avoid import the same thing twice use the wrappers #ifndef DEFINITION_OF_HEADER #define DEFINITION_OF_HEADER ... #endif you can also use #pragma once JS Common JS use require and exports. require can load ES modules when the file is .mjs ES modules are more flexible you can define queries, properties, etc. Python import Python uses importlib as the underlying machinary for importing. components of import are available through importlib to make it possible for you to create a custom object. import calls __import__(). importer is a term that refers to a both finds and loads a module. the import command don’t put every single definition directly into the current scope, but only the module name. To access its internals, you must use module_name.<what you want>. is not required to be on the top of the file. it search, create a module object and binds a name, while __import__ only searches and creates the object. when module is not found it raises ModuleNotFoundError. The import statement find a module and loads it. define a name for this module in the current scope. The import statement using from find the module specified in from clause. for each name in import check if the name exists. If not, check if it’s a submodule. If not found raise ImportError. Otherwise import to the local namespace. using * it exposes all public data. members with _ are not exposed by default. if __all__ is defined, all names defined are exposed. Otherwise all public members. __all__ is a global variable per module. it imports all names into the current scope (except those which start with _). not recommended. Relative imports only works on packages contained one within the another. . for the current package and .. for one that’s a level up. PYTHONPATH add entries in sys.path. useful when we need to test a package without installing it. affects installed python versions/environments, only use when it’s really needed. sys.path first entry is the directory of the current script or the current directory when using -c or -m. sys.modules a dictionary that maps modules that were already loaded. it’s a cache. return a module ready to run. maps submodules as well. if an entry value is None python will raise an ModuleNotFoundError. sys.meta_path (meta hooks) Are called before any importing proccess so it can override the sys.path, frozen modules and even builtin ones. To register add a finder object in sys.meta_path if the whole list is check and every finder returns None, so the module cannot be handled, raising an ModuleNotFoundError, otherwise return a spec. it’s called multiple times for multilevel packages (foo.bar.baz, 3 times, ‘foo’, ‘foo.bar’, ‘foo.bar.baz’). python has 3 by default. For builtin modules, for frozen modules and for an import path. by default it can handle .py, .pyc and .so files. sys.path_hooks part of sys.path processing. is registered by adding an importer factory into sys.path_hooks. it checks if a path item can be handled. return an importer when an item can be handled, otherwise return ImportError. is consulted while traversing a package __path__. python uses this list to handle different types of files and locations, like from URLs, zip files, so files, .py files, etc. it’s used after python tries every single finder from sys.meta_path. If none works, it iterate over each sys.path_hooks entries and give it each possible value from sys.path. must call sys.path_importer_cache.clear() after adding a new factory to it Modules is a file containing statements and definitions. the module name is the filename, which can be accessed via __name__. can have executable statements that are executed only once when the module is imported. have its private namespace. when executed as a script its name (__name__) becomes __main__. when importing a module, it searches in this sequence: sys.builtin_module_names. sys.path (which includes the directory of the file, PYTHONPATH and the installation dependent directory site-packages). the dir() command is used to list all the names in a module builtins is a module that list everything that’s builtin python every module has a repr (representaion) depending of data like name, origin, etc. __pycache__ contains the cached modules that were previously built. python always ignore the cache when: they are directly loaded via CLI (it recompiles the module). when the module is a binary. to reduce the compiled size use: -O to remove assert statements -OO to remove asserts and __doc__ opt- to optimize the binary .pyc are only faster for loading not executing Packages collection of modules inside the package, when importing, python searchs in sys.path for the names. To find the submodules inside your package, each submodule must have a __init__.py file. when loading submodules with import python tries to find the name as a declarion/statement from the module, if it’s not find it tries to load as a submodule. In case it’s not found, it will raise and ImportError. when using import * it only import the names defined for that package, not every submodule name. you can use relative imports within the submodules to navigate quickly between code. you can also use ‘path’ to check which directory python search for the submodules. Any module that has a __path__ is a package. Regular Packages directories with __init__.py. Namespace Packages split a pacakge between multiple locations on disk. cannot contain __init__.py files. __path__ is read-only. at runtime you can use sys.path to discover them. __init__.py can be empty but can also run initialization code. when a module is imported, the __init__.py is executed. define a package. Import Protocol it has two parts when both are implement it’s called an importer. finder and loader can be the same object. finders it determines if a module can be found. return a module spec with all information needed for loading it. can’t point to whatever location, not requering to be in the local machine. can be a meta_path finder, which operates at the beggining of the importing proccess, and path_entry finder, which responsible for finding and loading modules and packages located via a string path entry. sys.path_importer_cache maintains a cache of finders objects. loaders don’t need to check for sys.modules, import will check it before. module execution. Overall Execution pipeline (Default pipeline as I understood) you use import it uses under the hood __import__() search the module at cache sys.modules if not found, run the meta hooks run the finder iteratively if no meta_path worked, it iterates over sys.path and sys.path_hooks trying to see if any of the paths can be handled check if .pyc file is up-to-date, when importing python files if not, it regenerates the file and save the new hash run loader returning a module object binds the module object into a name provided via import References https://www.grumpymetalguy.com/programming/python_importlib/ https://docs.python.org/3/library/importlib.html https://docs.python.org/3/reference/simple_stmts.html#import https://github.com/python/cpython/blob/3.14/Lib/importlib/init.py https://docs.python.org/3/glossary.html#term-importer https://docs.python.org/3/glossary.html#term-loader https://docs.python.org/3/glossary.html#term-module-spec https://realpython.com/ref/stdlib/importlib/ https://discuss.python.org/t/usage-of-all-in-init-py/17936/5 https://discuss.python.org/t/usage-of-pythonpath/18086/7 https://bic-berkeley.github.io/psych-214-fall-2016/using_pythonpath.html https://github.com/stas00/the-art-of-debugging https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html https://nodejs.org/api/modules.html https://nodejs.org/api/esm.html https://tc39.es/ecma262/#sec-modules https://docs.python.org/3/tutorial/modules.html https://docs.python.org/3/glossary.html#term-namespace-package https://docs.python.org/3/reference/datamodel.html#module.path https://docs.python.org/3/reference/import.html https://docs.python.org/3/library/sys.html#sys.modules https://docs.python.org/3/library/sys.html#sys.meta_path https://peps.python.org/pep-0302/ https://docs.python.org/3/library/sys.html#sys.path_importer_cache https://docs.python.org/3/glossary.html#term-portion https://micropython-stubber.readthedocs.io/en/main/50_frozen_stubs.html#frozen-modules https://github.com/python/cpython/blob/main/Python/frozen.c https://wiki.python.org/moin/Freeze https://docs.python-guide.org/shipping/freezing/ https://docs.python.org/3/library/sys_path_init.html https://docs.python.org/3/tutorial/classes.html#tut-scopes https://docs.python.org/3/library/compileall.html#module-compileall https://peps.python.org/pep-3147/ https://peps.python.org/pep-0420/ https://packaging.python.org/en/latest/guides/packaging-namespace-packages/ https://realpython.com/python-namespace-package/ https://docs.python.org/3/library/importlib.html#importlib.machinery.PathFinder.find_spec https://stackoverflow.com/questions/41990169/how-to-use-sys-path-hooks-for-customized-loading-of-modules https://stackoverflow.com/questions/31882967/why-are-pyc-files-created-on-import https://peps.python.org/pep-3147/#python-behavior https://medium.com/@utkarshshukla.author/what-is-a-pyc-file-visualizing-pythons-bytecode-generation-fcce8e6da679 https://peps.python.org/pep-0451/ https://github.com/python/cpython/blob/main/Lib/importlib/_bootstrap.py https://github.com/python/cpython/blob/main/Lib/importlib/_bootstrap_external.py https://github.com/python/cpython/blob/main/Lib/importlib/abc.py https://github.com/python/cpython/blob/main/Lib/importlib/_abc.py https://www.reddit.com/r/Python/comments/untwoc/syspath_hooks_is_fun_for_everyone_cfgimp_a_misuse/ https://docs.python.org/3/glossary.html#term-path-entry-finder https://docs.python.org/3/glossary.html#term-path-entry-hook https://snarky.ca/writing-a-zip-file-importer-the-path-hook-part-1/ https://rahul.gopinath.org/post/2018/09/07/python-importer/ https://docs.ploomber.io/en/latest/api/_modules/root/ploomber.SourceLoader.html

February 15, 2026 · 7 min · map[email:dpbm136@gmail.com name:Dpbm]

Moving my website from NextJS to HUGO

So, it’s been a long time since I first created my blog using NextJs and MongoDB. The previous setup was kind a mess. You can still check it on my github 966949eb6e321c5f8478d40fa07550b41351401f. This old version was relying deeply on Nextjs server components, mdx plugin and the amazing api capabilities. Wich was nice, and gave me a freedom I wouldn’t have in other environments, however it was so complicated to create new posts. ...

January 20, 2026 · 5 min · map[email:dpbm136@gmail.com name:Dpbm]

UV TLS issue

Recently, I’ve been working on a python project that required me to use the qiskit-ibm-runtime package to do some quantum stuff. So, the first thing I did was run: uv add python-dotenv qiskit-ibm-runtime then I created a simple snippet to test it: import os from dotenv import load_dotenv from qiskit_ibm_runtime import QiskitRuntimeService if __name__ == "__main__": load_dotenv() QiskitRuntimeService.save_account(channel="ibm_quantum_platform", token=os.getenv("IBM_KEY"), instance=os.getenv("CRN"), overwrite=True, set_as_default=True) │ service = QiskitRuntimeService() print(service.least_busy(filters= lambda b : not b.simulator and b.num_qubits >= 9)) and ran the script with: ...

December 17, 2025 · 5 min · map[email:dpbm136@gmail.com name:Dpbm]

Hill Climbing for trading

Hill Climbing for PETR4 stocks This project was a challenge propoused by our professor. The idea of this project, was to implement an AI agent to buy-sell PETR4 stocks using the hill climbing algorithm. To tackle this challenge, I used Octave and the data provided by InfoMoney PETR4. The algorithm My implementation uses the default hill climbing algorithm with some nuances. The agent starts with some stocks already bought and some spare money in hist wallet. ...

May 22, 2025 · 2 min · map[email:dpbm136@gmail.com name:Dpbm]

Ciências da computação dia 292

Dado: elementos brutos, sem significado Informação: Dado processado que auxilia na tomada de decisão Conhecimento: Maneira como os humanos entendem e interagem com as informações Níveis de Hierarquia de informação Operacional (base): operações rotineiras da empresa (pagamento, INSS, etc) Tática: usado para a tomada de decisões. Foca no ambiente interno da empresa. Gerado a partir dos dados operacionais Estratégicas: Foca no ambiente externo. Concorrentes, como está o mercado, etc. ...

May 13, 2025 · 1 min · map[email:dpbm136@gmail.com name:Dpbm]

Resolvendo o problema de local optima - NRainhas

for english version click here Durante nossas aulas de Inteligência artificial, estávamos estudando sobre algoritmos de busca, mais precisamente o algoritmo de busca informada Hill Climbing. Para aprender sobre esse algoritmo, o implementamos para resolver o problema das N-Rainhas. Vimos que este é um algoritmo muito bom para resolver o problema rapidamente, contudo este se mostra como muito propenso a ficar estagnado no ótimo local. Devido a isso, nosso professor João Ricardo Favan nos deu o desafio de encontrar uma maneira de diminuir as chances do algoritmo empacar no ótimo local, e é por isso que estamos aqui. ...

May 11, 2025 · 6 min · map[email:dpbm136@gmail.com name:Dpbm]

Análise e Projeto de Algoritmos - Parte 1

Algoritmo → procedimento computacional bem definido que recebe entrada(s) e devolve uma saída, sendo a descrição do problema a relação entre a entrada e como deve ser sua saída; Problema → descrição dos parâmetros e a descrição de como o resultado deve ser apresentado; Instância de um problema → todas as entradas possíveis de um algoritmo que respeitam suas restrições; A velocidade de um programa depende de diversos fatores, mas não necessariamente vai depender do hardware usado ou da tecnologia. ...

April 28, 2025 · 2 min · map[email:dpbm136@gmail.com name:Dpbm]

Ciências da computação dia 1

lógica e algoritmos, então aqui vão algumas anotações: Lógica: Arte de pensar maneiras de encontrar a solução para algum problema o mais importante de um algoritmo é a lógica não a ferramenta (linguagem de programação) Algoritmos: maneiras de resolver um problema usando a lógica passo a passo para resolver o problema obs: podem existir vários algoritmos que resolvem o mesmo problema Além de aprendermos os conceitos, foi dado uma breve explicação do que é necessário para criar um algoritmo, sendo assim foi nos explicado que para criar um algoritmo é necessário pensar em cada parte do problema o que será necessário usar para resolve-lo ...

April 28, 2025 · 3 min · map[email:dpbm136@gmail.com name:Dpbm]

Ciências da computação dia 10

agora para sistemas lineares, equações irracionais e equações biquadradas. Sistemas lineares duas equações que se correlacionam e possuem mais de uma incógnita. para resolver sistemas lineares um dos métodos apresentados foi o método da adição, para utilizá-lo, pegue os números que acompanham x e multiplique a parte de cima pelo número de x de baixo e o de baixo pelo de cima, lembrando que um desses dois deve ser transformado em negativo, após isso pegue as equações que resultaram e some as, lembrando que os valores de x ao serem somados devem resultar em 0, o resultado dessa soma será uma equação do primeiro grau simples de resolver. após resolver e encontrar o Y com isso, pegue qualquer uma das equações anteriores e substitua o Y. ...

April 28, 2025 · 2 min · map[email:dpbm136@gmail.com name:Dpbm]