This week, I will add in the scripting series an nice addition from zuMi, one of the member of the Haiku community.
Indeed, three weeks ago, he proposed an original and quite useful script - named "pkg_opener" - which opens the package corresponding to a file or folder given by the user.
You can find the details of the original script in this thread : https://discuss.haiku-os.org/t/haiku-scripting/10094/132
Please note the last proposed version must be fixed in order to use the "open" command correctly with the "${pkg_src}" variable.
Copy / paste the below script in Pe:
lpe /boot/home/config/non-packaged/bin/pkg_opener.sh
#! /bin/sh
# This shell script, given a file or directory, attempts to find
# the package it belongs to (if any) and opens that package
# Function to display usage information and exit
Usage ()
{
cat << EOF >&2
usage: $(basename "${0}") <file|dir>
EOF
exit 1
}
# Check if the first argument (a file or directory) is provided
if [ ! -z "${1}" ] ; then
# Store the argument as the target file
pkgd_file="${1}"
else
if [[ ! -t 0 ]] ; then
# Prompt the user with a file selection dialog (filepanel)
# Default directory is the system directory, filtering only files (fds)
pkgd_file=$(filepanel -d $(finddir B_SYSTEM_DIRECTORY) -k fds)
else
# If no argument and input is from a terminal, show usage
Usage
fi
fi
# Check if the selected/provided file/dir actually exists
if [ -e "${pkgd_file}" ] ; then
# Try to retrieve the package attribute from the file
# "catattr -d" reads the attribute "SYS:PACKAGE_FILE" (specific to Haiku)
# pkg_src=$(catattr -d SYS:PACKAGE_FILE "${pkgd_file}" 2>/dev/null)
# I'm using 'findpaths -p ${path_to_file} B_FIND_PATH_PACKAGE_PATH' instead
# hint by Lrrr https://discuss.haiku-os.org/t/haiku-scripting/10094/134
pkg_src=$(findpaths -p "${pkgd_file}" B_FIND_PATH_PACKAGE_PATH 2>/dev/null)
if [[ "${pkg_src}" ]] ; then
# If the attribute exists, open the corresponding package file
#open $(finddir B_SYSTEM_PACKAGES_DIRECTORY)/${pkg_src}
open ${pkg_src}
else
# If the file does not belong to any package, show an error
cat << EOF >&2
error: ${pkgd_file} does not belong to a package
EOF
exit 1
fi
else
# If the file doesn't exist, show usage
Usage
fi
Save the file.
Then add execution rights to the script:
chmod +x /boot/home/config/non-packaged/bin/pkg_opener.sh
Now let's test it!
What about identifying the package containing the "ls" command ?
In a Terminal type :
pkg_opener.sh /bin/ls
The corresponding package is "coreutils".
You can check if the script is working with the folder of a game like "AssaultCube":
pkg_opener.sh /boot/system/apps/AssaultCube
It's working fine, as the corresponding package is recognized:)
Please note, if you indicate any file inside the folder, the package will be recognized as well:
pkg_opener.sh /boot/system/apps/AssaultCube/ac_client
When the package is not found, the below message will be displayed :
What about improving this script?
The idea is that instead of indicating the full path of a file, we can rely on the "which" command (using the $PATH variable)
It means that a command like "ls" or "/bin/ls" will be recognized.
Let's write a function for that!
In a Terminal, open Pe editor on the "/boot/home/config/settings/profile" file :
lpe /boot/home/config/settings/profile
Copy / paste the below content at the end of the file :
openpackage()
{
if [ $# -ne 1 ]; then
echo "Usage: openpackage <file or application's folder>"
return 1
fi
input="$1"
# Check if the input is an existing file
if [ -x "$input" ]; then
file_location="$input"
else
file_location=$(which "$input" 2>/dev/null)
if [ -z "$file_location" ]; then
echo "Error: command '$input' not found in PATH."
return 1
fi
fi
package_path=$(findpaths -p "$file_location" B_FIND_PATH_PACKAGE_PATH)
if [ -z "$package_path" ]; then
echo "Error: could not find package path for '$file_location'."
return 1
fi
open "$package_path"
}
Reload the "profile" in order to have the openpackage() function recognized:
source /boot/home/config/settings/profile
Now let's test it!
In a Terminal, type:
openpackage /bin/ls
Working as expected:)
Now try:
openpackage ls
The improved version is working nicely.
You can also indicate a folder in the parameter :
openpackage /boot/system/apps/AssaultCube
And it will recognize the corresponding package as well.
Imagine you don't remember the package linked to a command you have installed a few months ago on your system?
For instance, do you remember to which package "nslookup" is refering to?
In a Terminal type:
openpackage nslookup
The "bind_utils" package has been identified:)
In case the package can't be identified the below error will be displayed:
Do you find this script useful ?
You can put a comment below to share your opinion.