How to use the Ubuntu
Introduction
As far as I have noted, I will force myself to write all my blogs in English. So, if you are lucky or unlucky, you have read this blog, and I hope it can be helpful to you. Reading an English document can be a tricky task, as well as writing a blog in English.
In this blog, I will record all the problems that I encountered and the possible feasible solutions to them (you know, no model of solution is universal), including my train of thought.
And I'll avoid any unnecessary usage of images because the official document always has no images.
I'll write the references at the end of this article, if you are interested in them, just visit them. And I also will mention some of them in the relevant part of the article.
And, as I'm still a beginner at coding, and my mother tongue is not English, but Chinese, if there are any problems, point them out and try to let me know.
Emm, as this blog is so long I might have no mood to overwrite it in Chinese again.
Using English can prevent the fool from copying others' blogs without any needed illustrations and make the readers think more about it(as time goes by, you will have to take tea with the projects or documents that are written in English, you could just regard my article as the first step for you to adapt the environment of English, and I'll try my best to make my blog be friendly to read, using the words that human can realize not like those using words just like the alien), at least in the world of our Chinese, just in my own opinion.
This blog needs to be updated in the future, I just hope that I'll have the time and mood to do so.
Note:
- My system is
Ubuntu 24.04 LTS
. - I chose English as the default language option when I installed the Ubuntu system.
- All the references I will list at the end of this blog, are named
References
. - References don't mean that I use them in this blog, maybe I add them just because of that I regard them as supplementary material to the related part.
Catalog
目录- How to use the Ubuntu
- GRUB_DISABLE_OS_PROBER=false
Why my apt doesn't work
sudo apt update
, fail to connect.
Just like what we have done to Python, we should change the source of the Ubuntu to avoid such a kind of problem.
Visit https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/, and follow the guide, and then it works.
-
cd /etc/apt/sources.list.d/
-
sudo cp ubuntu.sources ubuntu.sources.bak
-
sudo vim ubuntu.sources
(My system isUbuntu 24.04 LTS
, apply the format of DEB822)Types: deb URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu Suites: noble noble-updates noble-backports Components: main restricted universe multiverse Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 # Types: deb-src # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu # Suites: noble noble-updates noble-backports # Components: main restricted universe multiverse # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换 Types: deb URIs: http://security.ubuntu.com/ubuntu/ Suites: noble-security Components: main restricted universe multiverse Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # Types: deb-src # URIs: http://security.ubuntu.com/ubuntu/ # Suites: noble-security # Components: main restricted universe multiverse # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # Types: deb # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports # Suites: noble-security # Components: main restricted universe multiverse # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # Types: deb-src # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports # Suites: noble-security # Components: main restricted universe multiverse # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # 预发布软件源,不建议启用 # Types: deb # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu # Suites: noble-proposed # Components: main restricted universe multiverse # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg # # Types: deb-src # # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu # # Suites: noble-proposed # # Components: main restricted universe multiverse # # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
-
sudo apt update
You may encounter this question fcitx-team-ubuntu-nightly-noble
not found 404.
Don't worry, just need to run this command sudo mv /etc/apt/sources.list.d/fcitx-team-ubuntu-nightly-noble.sources /etc/apt/sources.list.d/fcitx-team-ubuntu-nightly-noble.sources.bak
.
It works.
Emm, how can I run the AppImage
?
Problems I encountered
Sometimes, you can install the application by using the App Center
, and it is practicable for basic usage. But, if the software that you want to install is not accessible by the App Center
, you might turn to the website or other channel to access it.
Then, you may be confused about the things that I list below(e.g. https://b3log.org/siyuan/en/download.html):
-
AppImage
x86_64
arm64
-
deb
x86_64
arm64
-
tar.gz
x86_64
arm64
-
Source
As the recommended option is AppImage
, I will focus on it(If I need to introduce other options in the future, like deb
or tar.gz
, maybe I will make the supplement for it).
So, I installed it and didn't know how to run it. I clicked it like I have done in the Windows system, but it didn't work.
I realized it was time for me to STFW
, and I did it(if you are interested in it or just want to explore it in hand, you can click here).
AppImages require FUSE version 2 to run. Filesystem in Userspace (FUSE) is a system that lets non-root users mount filesystems.
So, if you want to run the AppImage, you need to install the FUSE. (For more details, just visit the https://github.com/AppImage/AppImageKit/wiki/FUSE)
-
Ubuntu>=24.04
sudo add-apt-repository universe sudo apt install libfuse2t64
-
Ubuntu>=22.04
sudo add-apt-repository universe sudo apt install libfuse2
Why do we use the AppImage
AppImage provides a way for upstream developers to provide “native” binaries for Linux users just the same way they could do for other operating systems.
It allow packaging applications for any common Linux based operating system, e.g., Ubuntu, Debian, openSUSE, RHEL, CentOS, Fedora etc.
AppImages come with all dependencies that cannot be assumed to be part of each target system in a recent enough version and will run on most Linux distributions without further modifications.
In conclusion, you can regard the AppImage as a universal format of applications that can be run in any common Linux.
In general, It is not installed on your system, so if you want to uninstall it, just remove it.
If it is automatically integrated with your desktop, you may need to remove the desktop files manually.
AppImage features:
- Distribution agnostic: Can run on various different Linux distributions
- No need of installing and compiling software: Just click and play
- No need for root permission: System files are not touched
- Portability: Can be run anywhere including live disks
- Apps are in read-only mode
- Software is removed just by deleting the AppImage file
- Applications packaged in AppImage are not sandboxed by default.
How to run the AppImage
You exactly have three methods to run an AppImage, by GUI, terminal, or desktop.
GUI
- Open your file manager and browse to the location of the AppImage
- Right-click on the AppImage and click the ‘Properties’ entry
- Switch to the Permissions tab and
- Click the ‘Allow executing file as program’ checkbox if you are using a Nautilus-based file manager (Files, Nemo, Caja), or click the ‘Is executable’ checkbox if you are using Dolphin, or change the ‘Execute’ drop down list to ‘Anyone’ if you are using PCManFM
- Close the dialog
- Double-click on the AppImage file to run
I think the guide from the official document is enough, and it did work when I had a try.
Terminal
Use the command chmod a+x <AppImage File>
, then you can double-click it to run it.
But if you want to run it by using ./<AppImage File>
, it can be a tricky task(maybe not, not every AppImage will cause such a kind of problem).
You can see that the error message may be shown like this:
[51026:0926/080644.846932:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /tmp/.mount_SiYuanBgR0wT/chrome-sandbox is owned by root and has mode 4755.
Trace/breakpoint trap (core dumped)
You might want to solve it in this way:
sudo chown root /tmp/.mount_SiYuanBgR0wT/chrome-sandbox
-
sudo chmod 4755 /tmp/.mount_SiYuanBgR0wT/chrome-sandbox
But it didn't work(It might work in some AppImage).
chown: cannot access '/tmp/.mount_SiYuanBgR0wT/chrome-sandbox': No such file or directory
You may not encounter this kind of problem in other AppImage files, but I'm not lucky enough.
But at least, I can double-click it to run it.
OK, may this command work. sudo ./SiYuan.AppImage
[0926/082147.923059:FATAL:electron_main_delegate.cc(295)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
Trace/breakpoint trap
sudo ./SiYuan.AppImage --no-sandbox
Many errors, and it didn't work. STFW
again, this time, I turn to askubuntu.com
for help.
Try this command ./SiYuan.AppImage --no-sandbox
.
It works, but it's not safe.
Someone provides a safe solution. But it didn't work for me.
SiYuan.AppImage --appimage-extract
SiYuan.AppImage: command not found
Now, go to the official document for possible help.
OK, it still didn't work for me, just put it aside.
Desktop
You might want to use the AppImage as how you use the Firefox, but how can it be searched in Show Apps
, and be added to the Dock
?
The answer is: .desktop
.
-
[sudo] vim
<AppImage file>.desktop
file(if you directly edit it on the location that I listed below, you may needsudo
) -
Edit it like this
[Desktop Entry] Encoding=UTF-8 Type=Application #Name of the Application Name=LANDrop #The path of the Application icon Icon=/home/user/图片/APP.svg #Whether open the terminal when starting it Terminal=false #The path of the AppImage Exec=/home/user/APP/APP.AppImage #The categories of the AppImage Categories=Utility;
-
After editing the
.desktop
file, you canmv
it to the location listed below(based on your request):-
/usr/share/applications/
- System Area, Showed to All users, Managed by System Package Manager.
-
/usr/local/share/applications/
- System Area, Showed to All users, Manually managed or installed.
-
~/.local/share/applications/
- Only Shown to the current user, Manually managed or installed.
-
-
Then you can use this command to make it able to execute
-
sudo chmod a+x <AppImage file>.desktop
(if the owner is root)- Also, you can use the
chown
to change the owner of this file.
- Also, you can use the
-
sudo chmod u+x <AppImage file>.desktop
-
-
After that, you can find it in your
Show Apps
, use it, or add it to theDock
.
Note: If you want to run SiYuan
, you may have to add the option --no-sandbox
to the Exec
.
How about creating the .desktop file automatic
If every time we have to write all of this manually, it is repetitive. So, how about writing a function in bash?
[Desktop Entry]
Encoding=UTF-8
Type=Application
#Name of the Application
Name=LANDrop
#The path of the Application icon
Icon=/home/user/图片/APP.svg
#Whether open the terminal when starting it
Terminal=false
#The path of the AppImage
Exec=/home/user/APP/APP.AppImage
#The categories of the AppImage
Categories=Utility;
Assume that I always put the AppImage file in the path like ~/Applications/<AppImage file dir>/<AppImage file>
.
We may only want to type the name of the application, and set the default value for the Encoding
, Type
, Terminal
, Exec
, and Categories
.
Remember this?
/usr/local/share/applications/
- System Area, Showed to All users, Mannually managed or installed
~/.local/share/applications/
- Only Showed to the current user, Mannually managed or installed
We can write the .sh
to achieve it.
-
For
~/.local/share/applications/
(In general, recommending to use this path)-
UInAppImage.sh
Used for init the AppImage to your desktop#!/bin/bash # Function to initialize an AppImage for the current user UInAppImage() { local app_dir local app_name_base local app_icon local use_default_icon_extension local use_default_icon_path local exec_options="" # Get the base directory where all AppImages are stored local appimage_base_dir=~/Applications # Check if the base directory for AppImages exists if [[ ! -d "$appimage_base_dir" ]]; then read -p "The directory $appimage_base_dir does not exist. Do you want to create it? (y/n): " create_dir if [[ "$create_dir" == "y" || "$create_dir" == "Y" ]]; then mkdir -p "$appimage_base_dir" if [[ $? -ne 0 ]]; then echo "Failed to create directory $appimage_base_dir." return 1 fi else read -p "Enter the full path for the AppImage directory: " appimage_base_dir if [[ ! -d "$appimage_base_dir" ]]; then echo "The specified directory does not exist." return 0 fi fi fi # Prompt the user for the AppImage file directory read -p "Enter the AppImage file directory (relative to $appimage_base_dir): " app_dir # Create the directory if it does not exist mkdir -p "$appimage_base_dir/$app_dir" # Validate if the AppImage directory was created successfully if [[ ! -d "$appimage_base_dir/$app_dir" ]]; then echo "Error: Failed to create AppImage directory." return 1 fi # Prompt the user for the base application's name (without .AppImage) read -p "Enter the base name of the application (do not include '.AppImage'): " app_name_base # Validate application base name if [[ -z "$app_name_base" ]]; then echo "Error: Application base name cannot be empty." return 1 fi # Construct the full application name with .AppImage local app_name="${app_name_base}.AppImage" local app_exec="$appimage_base_dir/$app_dir/$app_name" # Check if the AppImage file exists and add execute permissions if necessary if [[ -f "$app_exec" ]]; then echo "AppImage file found. Adding execute permissions..." chmod +x "$app_exec" else echo "Error: AppImage file does not exist." return 1 fi # Determine if the user wants to use the default .png extension for the icon read -p "Would you like to use the default .png extension for the icon? (y/n): " use_default_icon_extension if [[ "$use_default_icon_extension" == "y" || "$use_default_icon_extension" == "Y" ]]; then # Offer to use the default icon path read -p "Would you like to use the default icon path ($appimage_base_dir/$app_dir/)? (y/n): " use_default_icon_path if [[ "$use_default_icon_path" == "y" || "$use_default_icon_path" == "Y" ]]; then # Use default icon path app_icon="$appimage_base_dir/$app_dir/${app_name_base}.png" else # User wants to specify the icon path read -p "Enter the full path of the application icon: " app_icon fi else # Offer to use the default icon path without default extension read -p "Would you like to use the default icon path ($appimage_base_dir/$app_dir/) without default extension? (y/n): " use_default_icon_path if [[ "$use_default_icon_path" == "y" || "$use_default_icon_path" == "Y" ]]; then # Use default icon path without default extension app_icon="$appimage_base_dir/$app_dir/${app_name_base}" else # User wants to specify the icon path and extension read -p "Enter the full path of the application icon: " app_icon fi fi # Validate icon path if [[ ! -f "$app_icon" ]]; then echo "Error: Icon file does not exist." return 1 fi # Check if ~/.local/share/applications directory exists, create if not local desktop_dir="$HOME/.local/share/applications" if [[ ! -d "$desktop_dir" ]]; then echo "Creating $desktop_dir directory..." mkdir -p "$desktop_dir" fi # Create the .desktop file path local desktop_file_path="$desktop_dir/${app_name_base}.desktop" # Check if .desktop file already exists if [[ -e "$desktop_file_path" ]]; then read -p "A .desktop file already exists. Do you want to replace it? (y/n): " replace_desktop if [[ "$replace_desktop" != "y" && "$replace_desktop" != "Y" ]]; then echo "Operation canceled. The .desktop file was not replaced." return 0 fi # Remove the existing .desktop file rm "$desktop_file_path" fi # Prompt for adding --no-sandbox option to Exec read -p "Do you want to add --no-sandbox option to Exec? (y/n): " use_sandbox if [[ "$use_sandbox" == "y" ]]; then exec_options="--no-sandbox" fi # Create the .desktop file cat > "${app_name_base}.desktop" << EOF [Desktop Entry] Encoding=UTF-8 Type=Application Name=$app_name_base Icon=$app_icon Terminal=false Exec="$app_exec" $exec_options Categories=Utility; EOF # Make the .desktop file executable chmod +x "${app_name_base}.desktop" # Move the .desktop file to the applications directory mv "${app_name_base}.desktop" "$desktop_file_path" # Inform the user of the created .desktop file echo "The .desktop file has been created at: $desktop_file_path" } # Call the function to initialize the AppImage for the current user UInAppImage
-
UUnAppImage.sh
Used for uninstall the AppImage(but may have some requirements to your construction of directories)#!/bin/bash # Function to uninstall an AppImage for the current user UUnAppImage() { local app_dir local app_name_base local app_exec local desktop_file_path local icon_file_path local appimage_base_dir=~/Applications # Base directory where all AppImages are stored # Prompt the user for the AppImage file directory read -p "Enter the AppImage file directory (relative to $appimage_base_dir): " app_dir # Prompt the user for the base application's name (without .AppImage) read -p "Enter the base name of the application (do not include '.AppImage'): " app_name_base # Construct the full application name with .AppImage app_exec="$appimage_base_dir/$app_dir/$app_name_base.AppImage" # Ask if the user wants to remove the AppImage file read -p "Do you want to remove the AppImage file? [y/N]: " remove_appimage if [[ "$remove_appimage" =~ ^[Yy]$ ]]; then if [[ -f "$app_exec" ]]; then echo "Removing AppImage: $app_exec" rm "$app_exec" # Check if the removal was successful if [[ $? -eq 0 ]]; then echo "AppImage removed successfully." else echo "Failed to remove AppImage." return 1 fi else echo "AppImage does not exist." return 1 fi else echo "Skipping removal of AppImage." fi # Ask if the user wants to remove the .desktop file read -p "Do you want to remove the .desktop file? [y/N]: " remove_desktop if [[ "$remove_desktop" =~ ^[Yy]$ ]]; then desktop_file_path="$HOME/.local/share/applications/$app_name_base.desktop" if [[ -f "$desktop_file_path" ]]; then echo "Removing .desktop file: $desktop_file_path" rm "$desktop_file_path" if [[ $? -eq 0 ]]; then echo ".desktop file removed successfully." else echo "Failed to remove .desktop file." fi else echo ".desktop file does not exist." fi else echo "Skipping removal of .desktop file." fi # Ask if the user wants to remove the application icon read -p "Do you want to remove the application icon? [y/N]: " remove_icon if [[ "$remove_icon" =~ ^[Yy]$ ]]; then icon_file_path="$appimage_base_dir/$app_dir/${app_name_base}.png" if [[ -f "$icon_file_path" ]]; then echo "Removing icon file: $icon_file_path" rm "$icon_file_path" if [[ $? -eq 0 ]]; then echo "Icon file removed successfully." else echo "Failed to remove icon file." fi else echo "Icon file does not exist." fi else echo "Skipping removal of icon file." fi # Ask if the user wants to remove the AppImage directory read -p "Do you want to remove the AppImage directory ($app_dir)? [y/N]: " remove_app_dir if [[ "$remove_app_dir" =~ ^[Yy]$ ]]; then app_dir_path="$appimage_base_dir/$app_dir" if [[ -d "$app_dir_path" ]]; then echo "Removing AppImage directory: $app_dir_path" rm -r "$app_dir_path" if [[ $? -eq 0 ]]; then echo "AppImage directory removed successfully." else echo "Failed to remove AppImage directory." fi else echo "AppImage directory does not exist." fi else echo "Skipping removal of AppImage directory." fi echo "Uninstallation process completed." } # Call the function to uninstall the AppImage for the current user UUnAppImage
-
-
For
/usr/local/share/applications/
-
AUInAppImage.sh
Used for init the AppImage#!/bin/bash # Function to initialize an AppImage for all users AUInAppImage() { local app_dir local app_name_base local app_icon local use_default_icon_extension local use_default_icon_path local exec_options="" local desktop_file_path # Get the base directory where all AppImages are stored local appimage_base_dir=~/Applications # Check if the base directory for AppImages exists if [[ ! -d "$appimage_base_dir" ]]; then read -p "The directory $appimage_base_dir does not exist. Do you want to create it? (y/n): " create_dir if [[ "$create_dir" == "y" || "$create_dir" == "Y" ]]; then mkdir -p "$appimage_base_dir" if [[ $? -ne 0 ]]; then echo "Failed to create directory $appimage_base_dir." return 1 fi else read -p "Enter the full path for the AppImage directory: " appimage_base_dir if [[ ! -d "$appimage_base_dir" ]]; then echo "The specified directory does not exist." return 0 fi fi fi # Prompt the user for the AppImage file directory read -p "Enter the AppImage file directory (relative to $appimage_base_dir): " app_dir # Create the directory if it does not exist mkdir -p "$appimage_base_dir/$app_dir" # Validate if the AppImage directory was created successfully if [[ ! -d "$appimage_base_dir/$app_dir" ]]; then echo "Error: Failed to create AppImage directory." return 1 fi # Prompt the user for the base application's name (without .AppImage) read -p "Enter the base name of the application (do not include '.AppImage'): " app_name_base # Validate application base name if [[ -z "$app_name_base" ]]; then echo "Error: Application base name cannot be empty." return 1 fi # Construct the full application name with .AppImage local app_name="${app_name_base}.AppImage" local app_exec="$appimage_base_dir/$app_dir/$app_name" # Check if the AppImage file exists and add execute permissions if necessary if [[ -f "$app_exec" ]]; then echo "AppImage file found. Adding execute permissions..." chmod +x "$app_exec" else echo "Error: AppImage file does not exist." return 1 fi # Determine if the user wants to use the default .png extension for the icon read -p "Would you like to use the default .png extension for the icon? (y/n): " use_default_icon_extension if [[ "$use_default_icon_extension" == "y" || "$use_default_icon_extension" == "Y" ]]; then # Offer to use the default icon path read -p "Would you like to use the default icon path ($appimage_base_dir/$app_dir/)? (y/n): " use_default_icon_path if [[ "$use_default_icon_path" == "y" || "$use_default_icon_path" == "Y" ]]; then # Use default icon path app_icon="$appimage_base_dir/$app_dir/${app_name_base}.png" else # User wants to specify the icon path read -p "Enter the full path of the application icon: " app_icon fi else # Offer to use the default icon path without default extension read -p "Would you like to use the default icon path ($appimage_base_dir/$app_dir/) without specifying the extension? (y/n): " use_default_icon_path if [[ "$use_default_icon_path" == "y" || "$use_default_icon_path" == "Y" ]]; then # Use default icon path without specifying the extension app_icon="$appimage_base_dir/$app_dir/${app_name_base}" else # User wants to specify the icon path and extension read -p "Enter the full path of the application icon: " app_icon fi fi # Validate icon path if [[ ! -f "$app_icon" ]]; then echo "Error: Icon file does not exist." return 1 fi # Check if /usr/local/share/applications directory exists, create if not local desktop_dir="/usr/local/share/applications" if [[ ! -d "$desktop_dir" ]]; then echo "Creating $desktop_dir directory..." mkdir -p "$desktop_dir" fi # Create the .desktop file path desktop_file_path="$desktop_dir/${app_name_base}.desktop" # Check if .desktop file already exists if [[ -e "$desktop_file_path" ]]; then read -p "A .desktop file already exists. Do you want to replace it? (y/n): " replace_desktop if [[ "$replace_desktop" != "y" && "$replace_desktop" != "Y" ]]; then echo "Operation canceled. The .desktop file was not replaced." return 0 fi # Remove the existing .desktop file rm "$desktop_file_path" fi # Prompt for adding --no-sandbox option to Exec read -p "Do you want to add --no-sandbox option to Exec? (y/n): " use_sandbox if [[ "$use_sandbox" == "y" ]]; then exec_options="--no-sandbox" fi # Create the .desktop file cat > "${app_name_base}.desktop" << EOF [Desktop Entry] Encoding=UTF-8 Type=Application Name=$app_name_base Icon=$app_icon Terminal=false Exec="$app_exec" $exec_options Categories=Utility; EOF # Make the .desktop file executable chmod +x "${app_name_base}.desktop" # Check if the user is root to determine if sudo is needed if [[ $EUID -ne 0 ]]; then echo "This action requires sudo privileges." sudo mv "${app_name_base}.desktop" "$desktop_file_path" if [[ $? -ne 0 ]]; then echo "Failed to move .desktop file. Please check your permissions." return 1 fi else mv "${app_name_base}.desktop" "$desktop_file_path" fi # Inform the user of the created .desktop file echo "The .desktop file has been created at: $desktop_file_path" } # Call the function to initialize the AppImage for all users AUInAppImage
-
AUUnAppImage.sh
Used for uninit the AppImage#!/bin/bash # Function to uninstall an AppImage for all users AUUnAppImage() { local app_dir local app_name_base local app_exec local desktop_file_path local icon_file_path local appimage_base_dir=~/Applications # Base directory where all AppImages are stored local use_default_icon_path # Check if the base directory for AppImages exists if [[ ! -d "$appimage_base_dir" ]]; then echo "The directory $appimage_base_dir does not exist." return 0 fi # Prompt the user for the AppImage file directory read -p "Enter the AppImage file directory (relative to $appimage_base_dir or absolute path): " app_dir # Construct the full application name with .AppImage read -p "Enter the base name of the application (including any non-default extension, do not include '.AppImage'): " app_name_base local app_name="${app_name_base}.AppImage" app_exec="$appimage_base_dir/$app_dir/$app_name" # Ask if the user wants to remove the AppImage file read -p "Do you want to remove the AppImage file? [y/N]: " remove_appimage if [[ "$remove_appimage" =~ ^[Yy]$ ]]; then if [[ -f "$app_exec" ]]; then echo "Removing AppImage: $app_exec" rm "$app_exec" if [[ $? -eq 0 ]]; then echo "AppImage removed successfully." else echo "Failed to remove AppImage." return 1 fi else echo "AppImage does not exist." return 1 fi fi # Determine if the user wants to use the default icon path read -p "Would you like to use the default icon path ($appimage_base_dir/$app_dir/)? (y/n): " use_default_icon_path if [[ "$use_default_icon_path" == "y" || "$use_default_icon_path" == "Y" ]]; then app_icon="$appimage_base_dir/$app_dir/${app_name_base}.png" else read -p "Enter the full path of the application icon: " app_icon fi # Ask if the user wants to remove the application icon if [[ -f "$app_icon" ]]; then read -p "Do you want to remove the application icon? [y/N]: " remove_icon if [[ "$remove_icon" =~ ^[Yy]$ ]]; then echo "Removing icon file: $app_icon" rm "$app_icon" if [[ $? -eq 0 ]]; then echo "Icon file removed successfully." else echo "Failed to remove icon file." fi fi else echo "Icon file does not exist." fi # Construct the .desktop file path desktop_file_path="/usr/local/share/applications/${app_name_base}.desktop" if [[ -f "$desktop_file_path" ]]; then read -p "Do you want to remove the .desktop file? [y/N]: " remove_desktop if [[ "$remove_desktop" =~ ^[Yy]$ ]]; then echo "Removing .desktop file: $desktop_file_path" if [[ $EUID -ne 0 ]]; then echo "This action requires sudo privileges." sudo rm "$desktop_file_path" else rm "$desktop_file_path" fi if [[ $? -eq 0 ]]; then echo ".desktop file removed successfully." else echo "Failed to remove .desktop file." fi fi fi # Ask if the user wants to remove the AppImage directory read -p "Do you want to remove the AppImage directory ($app_dir)? [y/N]: " remove_app_dir if [[ "$remove_app_dir" =~ ^[Yy]$ ]]; then app_dir_path="$appimage_base_dir/$app_dir" if [[ -d "$app_dir_path" ]]; then echo "Removing AppImage directory: $app_dir_path" rm -r "$app_dir_path" if [[ $? -eq 0 ]]; then echo "AppImage directory removed successfully." else echo "Failed to remove AppImage directory." fi else echo "AppImage directory does not exist." fi fi echo "Uninstallation process completed." } # Call the function to uninstall the AppImage for all users AUUnAppImage
-
OK, it works, though it's just a simple example and may not be friendly enough for everyone to use, as I can only make sure it works for myself with some simple test.
Maybe, one day I'll try to write the AppImage manager based on them. I hope that I'll be in the mood for it.
How about install the rime(or Chinese Input Method by step 3 and step 4)
Why I use the rime
Now, I can't type any Chinese on my System. As I had used the rime in my Windows System, I chose to use the rime as my Input Method Engine.
It's free, open, with no advertisements, and does not collect your data in secret.
Just my own opinion, habit, and preference.
Note: Through the step 3 and the similar operation of step 4 that I mentioned below, it seems like that you can choose the suitable Chinese Input Method Engine for the Ubuntu 24.04 LTS
. So, if you don't want to install the rime, just do step 3 and step 4(the operations of it are almost similar), then it will work.
Install the rime
Visit https://github.com/rime/home/wiki/RimeWithIBus and https://github.com/rime/home/wiki/RimeWithSchemata.
Rime 是跨平臺的輸入法軟件,Rime 輸入方案可通用於以下發行版:
- 【中州韻】 ibus-rime → Linux
- 【小狼毫】 Weasel → Windows
- 【鼠鬚管】 Squirrel → Mac OS X
So, for my System, I need to install the ibus-rime.
-
sudo apt-get install ibus-rime
-
Install the different input schema (optional)
-
sudo apt-get install librime-data-double-pinyin
-
sudo apt-get install librime-data-terra-pinyin librime-data-bopomofo
-
-
Settings->System->Region & Language->System->Manage Installed languages->Install/Remove Languages->Chinese(simplified)
-
Settings->Keyboard->Input Sources->Add Input Source->type Chinese, and choose
other
option->add theChinese(Rime)
-
Restart your system, you can use this command
sudo shutdown -r now
Then, you can use the rime.
Note: For step 3 and step 4, I have simplified some details like where are they, so, you might need to make it by STFW
, if you meet some problems during the process. But I promise that it will not be a tricky task.
Edit the rime for your personal preference
Rime is just a frame of Input Method, so, it allows you to set many personal configurations.
It's a little bit complicated, just to do it step by step.
Though the official document has given information for our configuration, it's still not very friendly for a primary user of it(especially for the user on Linux).
I write this part to record how I edit the configuration for myself, and hope it will be helpful to others who want to use the Rime as their Input Method on Linux.
Just some basic settings.
To start it
Visit https://github.com/rime/home/wiki/RimeWithSchemata.
- SharedData:
/usr/share/rime-data/
(do not edit it manually) - UserData:
~/.config/ibus/rime
(always edit this)
Note:
-
Do not edit the
*.yaml
directly(When the Rime update, all the*.yaml
will be overwritten, though you can choose not to update it).The recommended way to edit the schema is to create and edit
*.custom.yaml
instead.Use the
patch
to write the new settings or use the new value of the setting to replace the original one. -
Everytime you do any changes to the
*.yaml
, you need to run ibus restart
to deploy the Rime.
Change the Candidate words:
-
vim ~/.config/ibus/rime/default.custom.yaml
-
Write the content below.
patch: "menu/page_size": 9
-
Then
ibus restart
, works.
Note: The valid arrangement of it is [1,9]
, some release versions of the Rime can support 10
candidate words.
Vertical or horizontal:
-
vim ~/.config/ibus/rime/ibus_rime.custom.yaml
-
Write the content below.
patch: "style/horizontal": true
-
Then
ibus restart
, works.
Chinese(tradition) and Chinese(simplified):
- Type "ctrl+`"
- Select “朙月拼音.简化字”, it works.
How to use the grub
To start it
Well, I installed the Ubuntu first and installed the Windows secondly, now, I can't see the interface of the grub and don't know how to start the Windows.
In the past, I installed Windows first. After that, if you install the Ubuntu, it will offer you the option to install the Ubuntu for your Windows, as this process is automatically processed by the installer, I don't need to do anything manually. Except editing the grub file to allow me to select which system to start.
Now, as it may be a tricky task, just prepare yourself for it.
Start it with the grub file itself
Before any edit to the grub, we are supposed to know where are they and what the function of them at least.
-
Configuration file:
/etc/default/grub
If you change this file, run 'update-grub' afterwards to update
/boot/grub/grub.cfg.For full documentation of the options in this file, see:
info -f grub -n 'Simple configuration' -
Executable files' directory:
/etc/grub.d
All executable files in this directory are processed in shell expansion order.
00_*: Reserved for 00_header.
10_*: Native boot entries.
20_*: Third party apps (e.g. memtest86+).
The number namespace in-between is configurable by system installer and/or
administrator. For example, you can add an entry to boot another OS as
01_otheros, 11_otheros, etc, depending on the position you want it to occupy in
the menu; and then adjust the default setting via /etc/default/grub. -
Automatically generated file:
/boot/grub/grub.cfg
(Do not edit it directly)It is automatically generated by grub-mkconfig using templates
from /etc/grub.d and settings from /etc/default/grub
Based on the illustration above, we should turn to know more about the configuration file first.
Know more about the Configuration file of the grub
-
info -f grub -n 'Simple configuration'
-
vim /etc/default/grub
-
Read it but only focus on the information that you may need
-
Quote the value containing spaces or other special characters
-
GRUB_DEFAULT
- The default menu entry.
- value: number | the title of a menu entry | the special string 'saved'
-
GRUB_TIMEOUT
- Boot the default entry this many seconds after the menu is displayed unless a key is pressed.
-
0
: boot immediately without displaying the menu -
-1
: wait indefinitely -
number not in {0,-1}
: seconds the menu is displayed - Note: If the GRUB_TIMEOUT_STYLE is set to ‘countdown’ or ‘hidden’, the timeout is instead counted before the menu is displayed
-
GRUB_TIMEOUT_STYLE
-
Influence the behavior of the menu
-
{countdown, hidden}
: Before displaying the menu, GRUB will wait for the timeout set by ‘GRUB_TIMEOUT’ to expire- If <ESC> or <F4> are pressed, or <SHIFT> is held down during that time, it will display the menu and wait for input.
- If a hotkey associated with a menu entry is pressed, it will boot the associated menu entry immediately.
- If the timeout expires before either of these happens, it will boot the default entry.
- In the ‘countdown’ case, it will show a one-line indication of the remaining time.
-
-
-
Analyse-it
- So, if you find that your
GRUB_TIMEOUT=0
, you can't see the menu of grub, because it will boot the default entry immediately without displaying the menu. - If you can find that your
GRUB_TIMEOUT_STYLE=hidden
, without typing the{<ESC>, <F4>, <SHIFT>}
, you can't see the menu. - Besides, when the
GRUB_TIMEOUT_STYLE={countdown, hidden}
, if your value of timeout is low, as GRUB will wait for the timeout before displaying the menu, you still can't see the menu while typing the key{<ESC>, <F4>, <SHIFT>}
.
- So, if you find that your
Make the changes based on your requirements.
Don't forget to run sudo update-grub
, after any changes to the /etc/default/grub
.
Add the menu entry of my Windows to it
After the operations that we have done, we can see the grub menu now, but, we still can't find the menu entry of my Windows system.
Remeber the /etc/grub.d
?
For example, you can add an entry to boot another OS as
01_otheros, 11_otheros, etc, depending on the position you want it to occupy in
the menu; and then adjust the default setting via /etc/default/grub.
We need to add an entry to boot another OS, but how?
By STFW
, I have tried the methods listed below.
os-prober (X) Not work for me
Visit https://cn.linux-console.net/?p=10556.
-
sudo os-prober
/dev/nvme0n1p5:Windows 10:Windows:chain
-
sudo update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-45-generic
Found initrd image: /boot/initrd.img-6.8.0-45-generic
Found linux image: /boot/vmlinuz-6.8.0-31-generic
Found initrd image: /boot/initrd.img-6.8.0-31-generic
Found memtest86+x64 image: /boot/memtest86+x64.bin
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
Adding boot menu entry for UEFI Firmware Settings ...
done -
OK, check the
/etc/default/grub
If your computer has multiple operating systems installed, then you
probably want to run os-prober. However, if your computer is a host
for guest OSes installed via LVM or raw disk devices, running
os-prober can cause damage to those guest OSes as it mounts
filesystems to look for things.GRUB_DISABLE_OS_PROBER=false
-
Justice do I have the guest OSes? No.
GRUB_DISABLE_OS_PROBER=true
thensudo update-grub
- Host Machine: This is the physical computer that runs the hypervisor. It provides the underlying hardware resources for the virtual machines.
- Hypervisor: Also known as a virtual machine monitor (VMM), it is software that runs on the host machine's hardware and allows multiple operating systems to run on the host at the same time. The hypervisor presents hardware resources to the guest operating systems.
- Guest OS: This is the operating system installed within a virtual machine. It believes it is running directly on the hardware, but in reality, it is being managed by the hypervisor.
- Virtual Machine (VM) : A software implementation of a physical machine that runs an operating system. Each VM acts like a separate computer and can run its own operating system and applications.
-
Not work,
info -f grub -n 'Simple configuration'
‘GRUB_DISABLE_OS_PROBER’
The ‘grub-mkconfig’ has a feature to use the external ‘os-prober’
program to discover other operating systems installed on the same
machine and generate appropriate menu entries for them. It is
disabled by default since automatic and silent execution of
‘os-prober’ , and creating boot entries based on that data, is a
potential attack vector. Set this option to ‘false’ to enable this
feature in the ‘grub-mkconfig’ command. -
OK, set
GRUB_DISABLE_OS_PROBER=false
, still doesn't work at all, with the same error message above. Turn to the next method.
Boot-Repair tool (?) May work for me
Hmm, I don't wanna try this, for that I don't want to install too many unusual used software for my system, and I don't want to do the repetitive install and uninstall jobs, either.
But if you are interested in it, visit the https://help.ubuntu.com/community/Boot-Repair for detailed information.
info grub
for help (X) Not work for me
Now, it's time for us to read the document of the grub to find the possible solution to the tricky task.
-
info grub
and scan it for the information that we need -
Turn to "Booting"
-
How to boot different operating systems
-
Loading an operating system directly
-
Using kexec from userspace
-
Chainloading another bootloader
-
GRUB cannot boot DOS or Windows directly, so you must chain-load them.
-
For a Windows system on the first partition of the first hard disk:
menuentry "Windows" {
insmod chain
insmod ntfs
set root=(hd0,1)
chainloader +1
}
-
-
-
-
Turn to "Filesystem syntax and semantics"
-
device syntax:
(DEVICE[,PARTMAP-NAME1PART-NUM1[,PARTMAP-NAME2PART-NUM2[,...]]])
-
- ‘[]’ means the parameter is optional.
- BIOS and EFI disks use either ‘fd’ or ‘hd’ followed by a digit, like ‘fd0’, or ‘cd’.
- AHCI, PATA (ata), crypto, USB use the name of driver followed by a number.
- Memdisk and host are limited to one disk so it's referred just by driver name.
- RAID (md), ofdisk (ieee1275 and nand), LVM (lvm), LDM, virtio (vdsk), and arcdisk (arc) use intrinsic name of disk prefixed by driver name.
-
- Hostdisk: [fhc]d[0-9]* or hostdisk/
- crypto and RAID (md):
uuid/ - LVM: lvmid/
/
- Hostdisk: [fhc]d[0-9]* or hostdisk/
-
The syntax ‘(hd0)’ represents using the entire disk (or the MBR when installing GRUB), while the syntax ‘(hd0,1)’ represents using the first partition of the disk (or the boot sector of the partition when installing GRUB).
-
-
-
To start the grub command line to define the position of my Windows System
- Restart your system
- On the grub menu, type
c
to get into the grub command line -
ls
to see all the disks and their partitions -
ls
one by one to define which one is my Windows System - I find it on my
(hd0,msdos5)
-
Another way is to use
sudo fdisk -l
and observe the information to define it (It needs you to know clearly about step 3) -
Know the UUID of the Windows System
sudo blkid /dev/nvme0n1p5
/dev/nvme0n1p5: BLOCK_SIZE="512" UUID="7EF6B725F6B6DD19" TYPE="ntfs" PARTUUID="10d919dd-05"
UUID: 7EF6B725F6B6DD19
Type: ntfs
-
sudo vim /etc/grub.d/11_otheros
Write the content below.
#!/bin/sh menuentry "Windows 10" { insmod ntfs insmod chain search --fs-uuid --no-floppy --set=root 7EF6B725F6B6DD19 chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi }
-
sudo chmod +x 11_otheros
-
sudo update-grub
Didn't work! Errors occur.
OK, I don't know how to handle it anymore.
Install the Windows first, then install the Ubuntu (y) work for me
Yes, I just chose the old workable way to solve it.
But maybe I can learn how to boot my Windows by learning the /etc/grub.d
.
-
more 30_os-prober
OK, I don't know what it's talking about. -
sudo more /boot/grub/grub.cfg
As I have installed the system again, it's no wonder why there are some differences from the past information.### BEGIN /etc/grub.d/30_os-prober ### menuentry 'Windows 8 (on /dev/nvme0n1p1)' --class windows --class os $menuentry_id _option 'osprober-chain-12B062A8B06291D1' { insmod part_msdos insmod ntfs search --no-floppy --fs-uuid --set=root 12B062A8B06291D1 parttool ${root} hidden- drivemap -s (hd0) ${root} chainloader +1 } ### END /etc/grub.d/30_os-prober ###
-
Then explanation from the AI
-
menuentry 'Windows 8 (on /dev/nvme0n1p1)' --class windows --class os $menuentry_id
-
menuentry
: Defines a boot menu entry. -
'Windows 8 (on /dev/nvme0n1p1)'
: This is the name displayed in the boot menu, indicating that this option is for booting Windows 8 from the partition located at/dev/nvme0n1p1
. -
--class windows
: A classification option that tags the menu item as a Windows system. -
--class os
: Another classification option, indicating that this is an operating system. -
$menuentry_id
: This is a variable typically used to provide a unique identifier for the menu entry.
-
-
_option 'osprober-chain-12B062A8B06291D1' {
-
_option
: Defines a configuration option block, often used to store configurations related to the boot entry. -
'osprober-chain-12B062A8B06291D1'
: This is the name of the options block, usually related toosprober
(a tool for automatically detecting other operating systems).
-
-
insmod part_msdos
-
insmod
: Stands for "insert module," used to load modules for GRUB2. -
part_msdos
: A module that is used to recognize MS-DOS partition tables.
-
-
insmod ntfs
-
ntfs
: Another module that provides support for the NTFS file system, which is commonly used by Windows operating systems.
-
-
search --no-floppy --fs-uuid --set=root 12B062A8B06291D1
-
search
: Used to search for bootable devices. -
--no-floppy
: Tells GRUB not to search on floppy drives. -
--fs-uuid
: Specifies to search for a device based on the file system UUID. -
--set=root
: Sets the found device as the root device, which is used for subsequent booting processes. -
12B062A8B06291D1
: The file system UUID.
-
-
parttool ${root} hidden-
-
parttool
: A tool used to manipulate partitions. -
${root}
: The root device variable set by the previoussearch
command. -
hidden-
: The exact purpose of this parameter is unclear; it might be used to hide a partition.
-
-
drivemap -s (hd0) ${root}
-
drivemap
: Used to map drives. -
-s (hd0)
: Specifies the source drive to map,(hd0)
typically represents the first SCSI/IDE hard drive. -
${root}
: Maps to the previously found root device.
-
-
chainloader +1
-
chainloader
: Used to load another boot loader. -
+1
: Indicates that GRUB2 should load the boot loader from the next sector after the current location, which is usually the Windows boot sector.
-
-
-
Analyse-it
-
I need to boot a Windows System, so I need to use
--class windows
to tag this menu entry as a Windows System. -
This menu entry will boot an OS, so
--class os
is needed to tag it as an OS. -
I need to provide a unique identifier for the menu entry, so I use the
$menuentry_id
. -
My hard disk use the format of MBR, so it's needed to use
insmod part_msdos
. -
My Windows System use the NTFS file system, so I use the
insmod ntfs
. -
I need to search the bootable devices, so I use the
search
-
--no-floppy
: not to search on floppy drives -
--fs-uuid
: use file system UUID to search the bootable devices, we can usesudo blkid /where/os/is
to get it. -
--set=root
: Sets the found device as the root device
-
-
After searching the bootable devices......
-
parttool ${root} hidden-
This line is intended to interact with the partition table of the device identified by
${root}
. Here's a breakdown:-
parttool
: This is a command in GRUB2 used for partition manipulation. It's typically used to perform operations on partitions that are not directly accessible due to BIOS or EFI constraints, or to handle certain types of partitions that GRUB2's standard commands can't interact with. -
${root}
: This is a variable that represents the root device as determined by a previoussearch
command. It's used to refer to the device or partition where the boot process should proceed. -
hidden-
: This is indeed a bit ambiguous without more context. In GRUB2, theparttool
command is used to mark a partition as hidden or to change its bootable flag. However, thehidden-
option does not correspond to any standard GRUB2parttool
operation. It's possible that this is a typo or a custom modification. The correct operation might behidden
followed by a partition number to hide a specific partition, orbootable
followed by a partition number to set its bootable flag.
-
-
drivemap -s (hd0) ${root}
This line is used to map a drive for the purpose of the boot process:
-
drivemap
: This command in GRUB2 is used to map a BIOS drive to a GRUB device. This mapping is necessary because GRUB uses its own naming scheme for drives that may not correspond to the BIOS's drive numbering. -
-s (hd0)
: The-s
option specifies the source drive for the mapping.(hd0)
is a GRUB device reference that typically denotes the first hard disk drive detected by GRUB. The notation in parentheses is a legacy way of referring to drives and might be used for compatibility reasons. -
${root}
: As mentioned before, this variable holds the device specification set by a previoussearch
command. In the context ofdrivemap
,${root}
is used to define the target of the mapping, meaning that(hd0)
in the BIOS is mapped to whatever device${root}
refers to within GRUB.
-
-
OK,
info grub
for more help.
-
-