This section contains useful Linux hints and tips collected over time.
To know what libraries are used in a .so or .a file, run the command ldd <library>.
Example:
pi@librecomputer:~/mystuff/jni/Gpiod/out $ ldd libgpiodgvc.so
/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v8l.so (0xf7939000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xf77e5000)
libgpiod.so.2 => not found
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xf77b8000)
/lib/ld-linux-armhf.so.3 (0xf7960000)
In the example above, we can see the libraries used in the libgpiodgvc.so shared object.
One thing that is to be noted: the library libgpiod.so.2 is not found. For the other external libraries used we can see what version of it is applied.
Checking the version of the GCC or G++ compiler can be done with a simple application check_32_or_64.cpp:
#include<stdio.h>
#include<stdlib.h>
int main(){
int*pointer;
int pointersize = sizeof(pointer);
printf("test\n");
printf("Pointer size = [%d], so gcc compiler is [%s] version.\n", pointersize, ((pointersize == 4) ? "32 bit" : "64 bit"));
return 0;
}
Compiling is done using the command gcc check_32_or_64.cpp -o check.
Running this will show the size of a pointer. If it's 4 then the compilers used are 32 bit compilers. Else, they are 64 bit compilers.
If you want to see the functions in a shard object (.so) or archive (.a) file, run the following command:
objdump -TC <name_of_so_or_a_file>
Example applied on the libgpiod.so file:
objdump -TC libgpiod.so
The output will be shown on screen. If you want to redirect it to a file, append "> outputfile.txt" to the command.
The content of the output will by default not be sorted. To sort the output, append "| sort" to the command.
To have sorted output to a file, the complete command for this example is objdump -TC | sort > output.txt. This will give you all lines in a sorted way, make it easier to search for functions in the library since they're alphabetically sorted.
readelf -Ws <library>.so is also a possibility which might give more/other interesting information.
xosview is an alternative for htop if you only want to see the parameters like load, CPU, memory, disk in a graphical representation.
Can be installed using sudo apt install xosview
By default the CPU is shown as a moving target, scrolling the data in a horizontal way.
If you want to see the CPU in another shape, that is, a bar that grows from left to right, then the parameter xosview*cpuGraph in /etc/X11/app-defaults/XOsview has to be changed from True to False.
Different possibilities:
sudo find / | grep <string>: will find all locations starting from the root and containing the <string> in the name
sudo find / -type f -name java: will find all files (-type f) that contain the exact name java (-name)
Example: sudo find / -type f -name mcp23017.o will find the exact name mcp23017.o, if present.
sudo find / -type d -name src: will find all directories (-type d) that contain the exact name src (-name)
Packages installed with sudo apt can easily be uninstalled with the command sudo apt --purge remove <package>.
To know if the package is installed, run the command dpkg --list or dpkg --list | grep <package_name> if you know the package name.
Example:
Suppose you want to completely remove all files that have been installed using the command sudo apt install libgpiod2 libgpiod-dev.
In this case, you should run the command dpkg --list | grep libgpiod to see if the package is indeed still available:
pi@rb3bplus:~ $ dpkg --list | grep libgpiod
ii libgpiod-dev:armhf 1.6.2-1+rpi1 armhf C library for interacting with Linux GPIO device - static libraries and headers
ii libgpiod2:armhf 1.6.2-1+rpi1 armhf C library for interacting with Linux GPIO device - shared libraries
Once confirmed, you can run the command sudo apt --purge remove libgpiod2 libgpiod-dev. This is the feedback you will get:
pi@rb3bplus:~ $ sudo apt --purge remove libgpiod2 libgpiod-dev
sudo: unable to resolve host rb3bplus: Name or service not known
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
gpiod* libgpiod-dev* libgpiod2*
0 upgraded, 0 newly installed, 3 to remove and 0 not upgraded.
After this operation, 521 kB disk space will be freed.
Do you want to continue? [Y/n]
. (after answering 'y' or simply press "enter" to accept the default choice 'Y')
(Reading database ... 48159 files and directories currently installed.)
Removing gpiod (1.6.2-1+rpi1) ...
Removing libgpiod-dev:armhf (1.6.2-1+rpi1) ...
Removing libgpiod2:armhf (1.6.2-1+rpi1) ...
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u5) ...
Running dpkg --list | grep libgpiod again will result in this output:
pi@rb3bplus:~ $ dpkg --list | grep libgpiod
pi@rb3bplus:~ $
Note that also the related header files (in this case, gpiod.h and gpiod.hpp) are removed. Ideally, nothing is left behind after the purge command.
Listing symbols in a C library: nm -gD <library>.so
Listing symbols in a CPP library: nm -gDC <library>.so
To share a folder in Windows to exchange data from/to a Linux image running in Virtual Box, the following conditions have to be met on a Windows 10 Home Edition configuration:
Make sure your network settings are correct
Right-click on the network icon in the status bar
Select Open Network & Internet Settings
Select Status in the left column
Click on Network and Sharing Center
Click on Change advanced sharing settings
Make sure the following items are selected:
Turn on network discovery and the checkbox Turn on automatic setup of network connected devices.
Turn on file and printer sharing
Save the changes if needed
Choose a place to create a folder you want to share, e.g. <drive_letter>:/<directory>/VmSharedFolder
Right-click on the directory and select Properties in the context menu
Select the Sharing tab: it should show Not Shared
Press the Share... button, check the people to share with and press the Share button. After giving permissions you should see Your folder is shared and the folder should have a small share icon in its name when going back to the explorer window.
If neeced, you can also press the Advanced Sharing button in the Properties window, then press the Permissions button. Here you can fine tune the permissions for one or more people/groups on that shared folder. By default, everyone has all permissions.
On the Linux machine, open a terminal (Ctrl-Alt-T) and check if CIFS is installed (Common Internet File System) by running the command sudo mount.cifs.
If installed, you will get a plethora of options telling you what's possible.
If not installed, run the command sudo apt install cifs-utils
Choose a location where you want to create the mount directory. E.g. ~/mystuff/win_share.
Run the following command:
sudo mount.cifs //Windows/SharedFolder /mnt/share -o user=account
where:
Windows is the IP address of your Windows computer. To know this address, open a command box in Windows and run the command ipconfig and look in the output for the IP address.
SharedFolder is the name you gave to the shared folder directory in Windows
share is the name you gave to the Linux mounting point
account is your Windows user account
You will be requested to give the sudo password and shortly after the Windows password. This is the password you're using to log in into Windows.
Example:
xxxxxxxxxx:~$ sudo mount.cifs //<Win_IP_Address>/<Shared_folder_name> /home/<user>/<mounting_point_name> -o user=<Windows_User>
Password for <Windows_User>@//<Win_IP_Address>/<Shared_folder_name>: <your_windows_password>
If all goes fine, the sharing should be in place. To test this, create an empty text file in the mount directory on Linux and check if you can see the file in Windows.
When using SSH to connect to the Raspberry Pi you can use the parameter -X to start graphical applications on the Raspberry Pi and show the result on Linux without any hassle.
I have a VM running Linux Mint 21 and when I connect to the Raspberry Pi using the command ssh -X pi@192.168.xxx.xxx, followed by, for example, running an immediateC application ./bar -l I see the iClive and iCbar GUI on my Linux VM. Extremely handy!
Only one limitation: you can only run one application at a time, you can't show the whole Raspberry Pi desktop on the Linux machine that way.
To be able to do that, you have to use something like VNC, running it as server on the Raspberry Pi and then running the VNC clients on Windows or Linux.
A much better solution is to use WSL2 on the Windows machine and from there start an XFCE GUI from where you can then connect remotely to the Raspberry Pi devices. See WSL2 for more information.
To be able to log in "automatically" from a client into the Raspberry Pi, you should generate a private/public key on the client. This can be done - also on Windows if the necessary SSH tools are installed - using the application ssh-keygen. Below are the steps to take for a Linux environment:
In an command window, run the command ssh-keygen -t rsa -b 4096
This will create a key based on the RSA algorithm (most used) with a bit length of 4096 bytes. This is a very strong encryption method.
During the key generation you will be asked to provide a pass phrase: simply press the Enter key (that is, do not provide a pass phrase else you have to give this each and every time you want to do an SSH connection with the sever and that's exactly what you do not want to do).
When asked where and how to store the keys, just accept the default names and location. Both private and public key will be stored in ~/.ssh on the client and the name will be id_rsa (private key) and id_rsa.pub (public key, obviously...).
The next thing is to get the id_rsa.pub key on the SSH server side. This can be done in two ways:
You open the file id_rsa.pub and copy the content of that file into the authorized_keys file on the SSH server. That is quite cumbersome, but doable.
A more user-friendly way is to use the ssh-copy-id command (part of the SSH keygen suite) on the client machine and type the following command:
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@<RPi_IP_Address>
You will be asked to give the password for the Raspberry Pi.
Once the copy action is over, the public key of the client is added at the end of the file authorized_keys in the /home/pi/.ssh directory on the Raspberry Pi (running the SSH server). You can cross-check this.
Once this is all done, the next time you log in into the Raspberry Pi using the ssh command you won't need to give your password anymore. The private/public key exchange mechanism will be triggered and the rest happens automatically "behind the scenes".
When creating a pair of private/public keys, how does this work?
There are 2 types of encryption keys: symmetrical and asymmetrical keys.
These kind of keys are used to both encrypt and decrypt the message. So, when a message is encrypted with the key it must be decrypted with the very same key.
This is a key that has two parts: a private key and a public key. They are, however, mathematically related to each other.
When the message is encrypted with the private key it has to be decrypted with the public key
When the message is encrypted with the public key, it has to be decrypted with the private key
Those are two extreme important properties of the asymmetrical keys principle!
First of all, a private/public key pair has to be generated. This is done - on Linux - using the ssh-keygen application, as described in the section above called "Generating private/public keys".
After the generation we have a private and a public key on the device that generated the keys. The private key NEVER leaves the device!
So, when you for example register to a webserver using the private/public key handshake you have to place your public key on the webserver. The webserver saves the public key for that user in its database.
It's not a problem at all the server knows your public key, hence public.
The next step is that the user wants to log in into the webserver. The user sends its username to the webserver and asks to log in.
Then, the webserver takes the public key of the user from its database and will create a sort of a challenge. That challenge can contain a timestamp and other stuff. The webserver will encrypt that challenge with the public key of the user and send it over to the computer of the user.
Once it arrives at the user's PC, the encrypted challenge is decrypted with the private key. Remember, a message encrypted with a public key can only be decrypted with the private key (and vice versa)!
The user's PC is able to decrypt the message and will prepare a response for the webserver to prove the challenge message has been received and understood (after decryption).
The response will be encrypted with the private key of the user and will be send over to the webserver.
Once the webserver receives the response of the user it will decrypt the message again with the public key. Only then, the webserver will know, based on the answer, if the response is correct or not.
So, the webserver will check if the challenge it has sent matches with the response it has received.
All the above is known as FIDO: Fast IDentity Online. The most important thing? Getting rid of passwords.
So, we have the following advantages:
Private key on the device
Public key shared
This is MFA
No phishing for your password anymore
Not possible to replay your encrypted password, should it be intercepted by a hacker
No need for passwords anymore
The command prompt is usually created by combining the user name, the at sign and the hostname. An example is geertvc@Win10.
If you want to see another "postfix" you have two options:
Change the content of the PS1 command in the .bashrc file:
Open the ~/.bashrc file.
Search for PS1.
If you find the rule where also "debian_chroot" is seen, you're at the right spot.
Change the \h in that line with the postfix you want to see.
Once saved, open a new command window and the command prompt will have your changes.
Note that this method does NOT change the hostname parameter itself.
Change hostname itself
This is the preferred method since you can change hostname to a string you like and this will be propagated throughout the whole Linux system.
To do this, run the command sudo hostnamectl set-hostname wsl2 (that is, if you want your hostname to be wsl2).
Another action to be done is to change the current hostname in the file /etc/hosts.
Open this file as sudo and search for the current host name assigned to IP address 127.0.1.1
In my case, this was 127.0.1.1 Win10. Win10
Replace the host names with the ones you want.
The result is now: 127.0.1.1 wsl2. wsl2
See also this section.
Search for text in a (sub)directory: grep -rnw '/path/to/somewhere/' -e 'pattern'
Example: grep -rnw . -e '6001' will search all files recursively - starting from the current directory - for the pattern 6001 and show them on the command line