I have a bash script where the error is in the list I think. I have searched here an on the internet, I even tried the dreaded AI but I think this needs a human to help. I do not understand why the script expects an operand:
#!/bin/bash
set -o nounset
set -o errexit
set -o pipefail
# Help message displayed with -h or --help option
help_message() {
cat << EOF
This script analyzes the dependencies of commands for creating minimal container environments.
Usage:
$(basename "$0") [OPTIONS] COMMANDS...
Options:
-h, --help Display this help message and exit.
Arguments:
COMMANDS... Space-separated list of commands to analyze dependencies for.
Example:
Analyze dependencies of ffmpeg and ffprobe:
./$(basename "$0") ffmpeg ffprobe
EOF
}
# Process command line options
if [[ $# -eq 0 ]]; then
echo "Error: Please provide at least one command." >&2
help_message
exit 1
fi
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
help_message
exit 0
fi
# Install dependencies
dpkg -s file >/dev/null 2>&1 || ( sudo apt install -qqq file -y )
# Function to check file type and add dependencies to the array
check_file() {
local f=$1
# Resolve the full path and follow symbolic links
local full_path
full_path=$(readlink -f "$f")
# Add the binary to the unique binaries list
unique_bins["$full_path"]=1
local filetype
filetype=$(file "$full_path")
echo "File: $full_path"
echo "Type: $filetype"
if [[ $filetype == *"dynamically linked"* ]]; then
echo "Processing dependencies..."
local deps
deps=$(ldd "$full_path" | awk '{print $3}' | grep '/')
for dep in $deps; do
# Resolve the full path for dependencies as well
local dep_full_path
dep_full_path=$(readlink -f "$dep")
unique_libs["$dep_full_path"]=1
done
elif [[ $filetype == *"statically linked"* ]] || [[ $filetype == *"not a dynamic executable"* ]]; then
echo "This is a statically linked executable or not a dynamic executable."
else
echo "This is not an executable file."
fi
echo "------------------------------------"
}
# Analyze a command's runtime dependencies using strace (with multiple scenarios)
analyze_with_strace() {
local cmd=$1
strace -e trace=file "$cmd" 2>&1
| grep "^open" | awk -F'"' '!/= -1 ENOENT/ { print $2 }'
| grep -v -e "^/root" -e "^/tmp" -e "^/sys" | sort -u | while read -r lib; do
local lib_path
lib_path=$(readlink -f "$lib")
unique_libs["$lib_path"]=1
done
}
# Handle command line arguments (loop through all passed arguments)
for cmd in "$@"; do
# Find the primary binary location
cmd_path=$(which "$cmd" 2>/dev/null)
if [[ -x "$cmd_path" ]]; then
check_file "$cmd_path"
echo "Primary $cmd found at $cmd_path"
# Runtime dependency analysis with strace
analyze_with_strace "$cmd_path"
else
echo "Command $cmd not found in PATH"
fi
done
# Find all instances of the command in the file system
find / -type f -name "$cmd" 2>/dev/null -print0 | while IFS= read -r -d '' file; do
if [[ "$file" != "$cmd_path" ]]; then
check_file "$file" # Pass the path to the function
echo "Found $cmd at $file"
fi
done
# Print unique dependencies and binaries together
for lib in "${!unique_libs[@]}"; do
echo -n "--include-path $lib "
done
for bin in "${!unique_bins[@]}"; do
echo -n "--include-bin $bin "
done
echo "--include-shell"
When I run it with tree
as an example:
❯ ./get_deps_libs.sh tree
./get_deps_libs.sh: line 51: /usr/bin/tree: syntax error: operand expected (error token is "/usr/bin/tree")
2