Skip to content

Instantly share code, notes, and snippets.

@jbranchaud
Created April 1, 2025 16:14
Show Gist options
  • Save jbranchaud/53e0ea2e31db5ff97fa5ad72dad5ccc2 to your computer and use it in GitHub Desktop.
Save jbranchaud/53e0ea2e31db5ff97fa5ad72dad5ccc2 to your computer and use it in GitHub Desktop.
A script that you can run against any file/path to get a bunch of details about it
#!/bin/bash
# file_info.sh - A script to provide comprehensive information about a file
# Usage: ./file_info.sh <filename>
set -e
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
print_header() {
echo -e "\n${BLUE}==== $1 ====${NC}\n"
}
print_section() {
echo -e "${CYAN}$1:${NC} $2"
}
print_error() {
echo -e "${RED}ERROR:${NC} $1"
}
print_warning() {
echo -e "${YELLOW}WARNING:${NC} $1"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
# Check if filename is provided
if [ $# -ne 1 ]; then
print_error "Usage: $0 <filename>"
exit 1
fi
FILENAME="$1"
# Check if file exists
if [ ! -e "$FILENAME" ]; then
print_warning "File '$FILENAME' does not exist in the current directory."
# Check if file was in git history
if git rev-parse --is-inside-work-tree &>/dev/null; then
if git log --all -- "$FILENAME" &>/dev/null; then
print_header "GIT HISTORY FOR DELETED FILE"
# Last commit that involved the file
LAST_COMMIT=$(git log -n 1 --pretty=format:"%h - %an, %ar : %s" -- "$FILENAME")
print_section "Last commit" "$LAST_COMMIT"
# When the file was deleted
DELETION_COMMIT=$(git log -n 1 --diff-filter=D --pretty=format:"%h - %an, %ar : %s" -- "$FILENAME")
if [ -n "$DELETION_COMMIT" ]; then
print_section "Deleted in commit" "$DELETION_COMMIT"
fi
# When the file was added
CREATION_COMMIT=$(git log --diff-filter=A --pretty=format:"%h - %an, %ar : %s" -- "$FILENAME")
if [ -n "$CREATION_COMMIT" ]; then
print_section "Added in commit" "$CREATION_COMMIT"
fi
fi
fi
exit 1
fi
print_header "BASIC FILE INFORMATION"
# Basic file information
print_section "File path" "$(realpath "$FILENAME")"
print_section "File size" "$(du -h "$FILENAME" | cut -f1)"
print_section "File type" "$(file -b "$FILENAME")"
if [ -f "$FILENAME" ]; then
print_section "Line count" "$(wc -l < "$FILENAME")"
FILEHASH=$(md5sum "$FILENAME" | cut -d ' ' -f 1)
print_section "MD5 hash" "$FILEHASH"
fi
# Owner and permissions
OWNER=$(stat -c '%U:%G' "$FILENAME")
PERMS=$(stat -c '%A' "$FILENAME")
print_section "Owner" "$OWNER"
print_section "Permissions" "$PERMS"
# Timestamps
print_section "Last modified" "$(stat -c '%y' "$FILENAME")"
print_section "Last accessed" "$(stat -c '%x' "$FILENAME")"
# Check if in git repository
if git rev-parse --is-inside-work-tree &>/dev/null; then
print_header "GIT INFORMATION"
# Get repo information
REPO_ROOT=$(git rev-parse --show-toplevel)
RELATIVE_PATH=$(realpath --relative-to="$REPO_ROOT" "$FILENAME")
print_section "Repository root" "$REPO_ROOT"
print_section "Path within repo" "$RELATIVE_PATH"
# Check if file is tracked by git
if git ls-files --error-unmatch "$FILENAME" &>/dev/null; then
print_success "File is under git version control"
# Check if file has modifications
if git diff --quiet -- "$FILENAME"; then
print_section "Status" "Clean (no modifications)"
else
print_section "Status" "Modified since last commit"
# Show a summary of changes
print_section "Changes summary" "$(git diff --stat "$FILENAME")"
fi
# Last few commits that modified the file
print_header "RECENT COMMIT HISTORY"
echo -e "$(git log -n 3 --pretty=format:"%h - %an, %ar : %s" -- "$FILENAME")"
# When the file was added to the repository
FIRST_COMMIT=$(git log --diff-filter=A --pretty=format:"%h - %an, %ar : %s" -- "$FILENAME")
print_header "ORIGIN INFORMATION"
if [ -n "$FIRST_COMMIT" ]; then
print_section "Added to repository in" "$FIRST_COMMIT"
else
print_warning "Could not determine when file was added to repository"
fi
else
print_warning "File is not under git version control"
# Check if file is ignored by git
if git check-ignore -q "$FILENAME"; then
print_section "Git status" "File is ignored by gitignore rules"
# Try to determine which rule ignores it
IGNORE_RULE=$(git check-ignore -v "$FILENAME" 2>/dev/null | awk '{print $2":"$3}')
if [ -n "$IGNORE_RULE" ]; then
print_section "Ignored by rule" "$IGNORE_RULE"
fi
else
print_section "Git status" "File is untracked but not ignored"
fi
fi
else
print_warning "Not inside a git repository"
fi
# Additional useful information based on file type
print_header "ADDITIONAL INFORMATION"
# For text files, provide some content insights
if file "$FILENAME" | grep -q text; then
if [ -f "$FILENAME" ]; then
print_section "Encoding" "$(file -b --mime-encoding "$FILENAME")"
# Check for shebang
SHEBANG=$(head -n 1 "$FILENAME" | grep -E "^#!" || echo "")
if [ -n "$SHEBANG" ]; then
print_section "Shebang" "$SHEBANG"
fi
# Check for potential secrets or sensitive info
if grep -q -E '(password|secret|token|key|credential)' "$FILENAME"; then
print_warning "File may contain sensitive information (passwords, keys, tokens, etc.)"
fi
# Check for TODO/FIXME comments
TODO_COUNT=$(grep -c -E 'TODO|FIXME' "$FILENAME" || echo "0")
if [ "$TODO_COUNT" -gt 0 ]; then
print_section "TODO/FIXME count" "$TODO_COUNT"
fi
fi
fi
# For executables, check execution bit
if [ -f "$FILENAME" ]; then
if [ -x "$FILENAME" ]; then
print_section "Executable" "Yes (execution bit is set)"
else
if file "$FILENAME" | grep -q -E 'executable|script'; then
print_warning "File appears to be executable but execution bit is not set"
fi
fi
fi
# For directories, show content summary
if [ -d "$FILENAME" ]; then
FILE_COUNT=$(find "$FILENAME" -type f | wc -l)
DIR_COUNT=$(find "$FILENAME" -type d | wc -l)
print_section "Contains" "$FILE_COUNT files in $DIR_COUNT directories"
print_section "Total size" "$(du -sh "$FILENAME" | cut -f1)"
fi
# For symlinks, show target
if [ -L "$FILENAME" ]; then
TARGET=$(readlink "$FILENAME")
print_section "Symlink target" "$TARGET"
if [ ! -e "$TARGET" ]; then
print_warning "Symlink target does not exist (broken link)"
fi
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment