#!/usr/bin/env bash # Fetch info about your system # https://github.com/dylanaraps/fetch # # Optional Dependencies: (You'll lose these features without them) # Displaying Images: w3m + w3m-img # Image Cropping: ImageMagick # Wallpaper Display: feh # Current Song: mpc # Text formatting, dynamic image size and padding: tput # Resolution detection: xorg-xdpyinfo # More accurate window manager detection: wmctrl # # Created by Dylan Araps # https://github.com/dylanaraps/ # Speed up script by not using unicode export LC_ALL=C export LANG=C export LANGUAGE=C # Config Options {{{ # Info Options {{{ # Info # What to display and in what order. # # Format is: "Subtitle: function name" # Additional lines you can use include: # "underline" "linebreak" "echo: msg here" "title: title here" # # You can also include your own custom lines by using: # "echo: subtitlehere: $(custom cmd here)" # "echo: Custom string to print" # # Optional info lines that are disabled by default are: # "getresolution" "getsong" info=( "gettitle" "underline" "OS: getdistro" "Kernel: getkernel" "Uptime: getuptime" "Packages: getpackages" "Shell: getshell" "Window Manager: getwindowmanager" "CPU: getcpu" "Memory: getmemory" "linebreak" "getcols" ) # Window Manager # Use wmctrl for a more accurate # window manager reading use_wmctrl=0 # CPU # CPU speed type # Only works on Linux # --speed_type current/min/max speed_type="max" # Uptime # Shorten the output of the uptime function uptime_shorthand="off" # Color Blocks # Color block range # --block_range start end start=0 end=7 # Toggle color blocks # --color_blocks on/off color_blocks="on" # Color block width # --color_block_width num block_width=3 # }}} # Text Colors {{{ # --colors 1 2 3 4 5 # --title_color num title_color=4 # --subtitle_color num subtitle_color=1 # --colon_color num colon_color=8 # --underline_color num underline_color=8 # --info_color num info_color=6 # }}} # Text Options {{{ # Toggle line wrapping # --line_wrap on/off line_wrap="on" # Toggle bold text # --bold on/off bold="on" # Toggle title underline # --underline on/off underline="on" # Underline character # --underline_char char underline_char="-" # Prompt height # You should only have to change this if your # prompt is greater than 2 lines high. # --prompt_height num prompt_height=1 # }}} # Image Options {{{ # Image Source # --image wall, shuffle, /path/to/img, off image="wall" # Thumbnail directory imgtempdir="$HOME/.fetchimages" # W3m-img path # Some systems have this in another location w3m_img_path="/usr/lib/w3m/w3mimgdisplay" # Split Size # Sizing for the img and text splits # The larger the value the less space fetch will take up. # The default value of 2 splits the image and text at # half terminal width each. # A value of 3 splits them at a third width each and etc. # --split_size num split_size=2 # Image position # --image_position left/right image_position="left" # Shuffle dir shuffledir="$HOME/Pictures/wallpapers/wash" # Crop mode # --crop_mode normal/fit/fill crop_mode="normal" # Crop offset # Only affects normal mode. # --crop_offset northwest/north/northeast/west/center # east/southwest/south/southeast crop_offset="center" # Font width # Used when calculating dynamic image size font_width=5 # Right gap between image and text # --gap num gap=4 # Image offsets # --xoffset px # --yoffset px yoffset=0 xoffset=0 # }}} # Other Options {{{ # Take a screenshot # --scrot on/off scrot="off" # Screenshot program to launch # --scrotcmd scrotcmd="scrot -c -d 3" # Scrot dir # Where to save the screenshots # --scrotdir /path/to/screenshot/folder scrotdir="$HOME/Pictures" # Scrot filename # What to name the screenshots # --scrot str scrotname="fetch-%Y-%m-%d-%H:%M.png" # }}} # }}} # Gather Info {{{ # Get Operating System Type case "$(uname)" in "Linux") os="Linux" ;; "Darwin") os="Mac OS X" ;; "CYGWIN"*) os="Windows" ;; esac # Get Distro case "$os" in "Linux" ) if type -p crux >/dev/null 2>&1; then distro="CRUX" else distro="$(grep -h '^NAME=' /etc/*ease)" distro=${distro#NAME\=*} distro=${distro#\"*} distro=${distro%*\"} fi ;; "Mac OS X") distro="Mac OS X $(sw_vers -productVersion)" ;; "Windows") case "$(cmd /c ver)" in *"XP"*) distro="Windows XP" ;; *"7"*) distro="Windows 7" ;; *"8.1"*) distro="Windows 8.1" ;; *"8"*) distro="Windows 8" ;; *"10"*) distro="Windows 10" ;; *) distro="Windows" ;; esac ;; *) distro="Unknown" ;; esac # Get Title gettitle () { title="${USER}@$(hostname)" } # Get kernel version getkernel() { kernel="$(uname -r)" } # Get uptime getuptime () { case "$os" in "Linux") uptime="$(uptime -p)" ;; "Mac OS X") # Get boot time in seconds boot="$(sysctl -n kern.boottime)" boot=${boot/{ sec = /} boot=${boot/,*} # Get current date in seconds now=$(date +%s) uptime=$((now - boot)) # Convert uptime to days/hours/mins mins=$((uptime / 60%60)) hours=$((uptime / 3600%24)) days=$((uptime / 86400)) case "$mins" in 0) ;; 1) uptime="up ${mins} minute" ;; *) uptime="up ${mins} minutes" ;; esac case "$hours" in 0) ;; 1) uptime="up ${hours} hour, ${uptime/up /}" ;; *) uptime="up ${hours} hours, ${uptime/up /}" ;; esac case "$days" in 0) ;; 1) uptime="up ${days} day, ${uptime/up /}" ;; *) uptime="up ${days} days, ${uptime/up /}" ;; esac ;; "Windows") uptime=$(uptime | awk -F ':[0-9]{2}+ |(, ){1}+' '{printf $2}') uptime=${uptime/ / } ;; *) uptime="Unknown" ;; esac if [ "$uptime_shorthand" == "on" ]; then uptime=${uptime/up/} uptime=${uptime/minutes/mins} uptime=${uptime# } fi } # Get package count getpackages () { case "$distro" in "Arch Linux"|"Parabola GNU/Linux-libre"|"Manjaro"|"Antergos") packages="$(pacman -Q | wc -l)" ;; "void") packages="$(xbps-query -l | wc -l)" ;; "Ubuntu"|"Mint"|"Debian"|"Kali Linux"|"Deepin Linux") packages="$(dpkg --get-selections | grep -v deinstall$ | wc -l)" ;; "Slackware") packages="$(ls -1 /var/log/packages | wc -l)" ;; "Gentoo"|"Funtoo") packages="$(ls -d /var/db/pkg/*/* | wc -l)" ;; "Fedora"|"openSUSE"|"Red Hat Enterprise Linux"|"CentOS") packages="$(rpm -qa | wc -l)" ;; "CRUX") packages="$(pkginfo -i | wc -l)" ;; "Mac OS X"*) packages="$(pkgutil --pkgs | wc -l)" packages=${packages//[[:blank:]]/} ;; "Windows"*) packages=$(cygcheck -cd | wc -l) ;; *) packages="Unknown" ;; esac } # Get shell getshell () { shell="$SHELL" } # Get window manager getwindowmanager () { if [ "$use_wmctrl" == "on" ]; then windowmanager="$(wmctrl -m | head -n1)" windowmanager=${windowmanager/Name: /} elif [ "$XDG_CURRENT_DESKTOP" ]; then windowmanager="$XDG_CURRENT_DESKTOP" elif [ -e "$HOME/.xinitrc" ]; then xinitrc=$(grep "^[^#]*exec" "${HOME}/.xinitrc") windowmanager="${xinitrc/exec /}" windowmanager="${windowmanager/-session/}" windowmanager="${windowmanager^}" else case "$os" in "Mac OS X") windowmanager="Quartz Compositor" ;; "Windows") windowmanager="Explorer" ;; *) windowmanager="Unknown" ;; esac fi } # Get cpu getcpu () { case "$os" in "Linux") # Get cpu name cpu="$(grep -F 'model name' /proc/cpuinfo)" cpu=${cpu/model name*: /} cpu=${cpu/ @*/} # Get cpu speed speed_type=${speed_type/rent/} read -r speed < \ /sys/devices/system/cpu/cpu0/cpufreq/scaling_${speed_type}_freq # Convert mhz to ghz without bc speed=$((speed / 100000)) speed=${speed:0:1}.${speed:1} cpu="$cpu @ ${speed}GHz" ;; "Mac OS X") cpu="$(sysctl -n machdep.cpu.brand_string)" ;; "Windows") # Get cpu name cpu="$(grep -F 'model name' /proc/cpuinfo)" cpu=${cpu/model name*: /} cpu=${cpu/ @*/} cpu=${cpu// /} cpu=${cpu% } # Get cpu speed speed=$(grep -F 'cpu MHz' /proc/cpuinfo) speed=${speed/cpu MHz*: /} speed=${speed/\./} # Convert mhz to ghz without bc speed=$((speed / 100000)) speed=${speed:0:1}.${speed:1} cpu="$cpu @ ${speed}GHz" ;; *) cpu="Unknown" ;; esac # Remove uneeded patterns from cpu output # This is faster than sed/gsub cpu=${cpu//(tm)/} cpu=${cpu//(TM)/} cpu=${cpu//(r)/} cpu=${cpu//(R)/} cpu=${cpu// CPU/} cpu=${cpu// Processor/} cpu=${cpu// Six-Core/} } # Get memory getmemory () { case "$os" in "Linux") # Read first 3 lines exec 6< /proc/meminfo read -r memtotal <&6 read -r memfree <&6 read -r memavail <&6 exec 6<&- # Do some substitution on each line memtotal=${memtotal/MemTotal:/} memtotal=${memtotal/kB*/} memtotal=${memtotal// /} memfree=${memfree/MemFree:/} memfree=${memfree/kB*/} memfree=${memfree// /} memavail=${memavail/MemAvailable:/} memavail=${memavail/kB*/} memavail=${memavail// /} memused=$((memtotal - memavail)) memory="$((memused / 1024))MB / $((memtotal / 1024))MB" ;; "Mac OS X") memtotal=$(printf "%s\n" "$(sysctl -n hw.memsize)"/1024^2 | bc) memwired=$(vm_stat | awk '/wired/ { print $4 }') memactive=$(vm_stat | awk '/active / { print $3 }') memcompressed=$(vm_stat | awk '/occupied/ { print $5 }') memused=$(((${memwired//.} + \ ${memactive//.} + \ ${memcompressed//.}) * 4 / 1024)) memory="${memused}MB / ${memtotal}MB" ;; "Windows") mem="$(awk 'NR < 3 {printf $2 " "}' /proc/meminfo)" # Split the string above into 2 vars # This is faster than using an array. set $mem memtotal=$1 memfree=$2 memavail=$((memtotal - memfree)) memused=$((memtotal - memavail)) memory="$((${memused%% *} / 1024))MB / " memory+="$((${memtotal%% *} / 1024))MB" ;; *) memory="Unknown" ;; esac } # Get song getsong () { song=$(mpc current 2>/dev/null || printf "%s" "Unknown") } # Get Resolution getresolution () { case "$os" in "Linux") resolution=$(xdpyinfo | awk '/dimensions:/ {printf $2}') ;; "Mac OS X") resolution=$(system_profiler SPDisplaysDataType |\ awk '/Resolution:/ {print $2"x"$4" "}') ;; *) resolution="Unknown" ;; esac } getcols () { if [ "$color_blocks" == "on" ]; then printf "${padding}%s" while [ $start -le $end ]; do printf "\e[48;5;${start}m%${block_width}s" start=$((start + 1)) # Split the blocks at 8 colors [ $end -ge 9 ] && [ $start -eq 8 ] && \ printf "\n%s${clear}${padding}" done # Clear formatting printf "%b%s" "$clear" fi } # Windows Specific Functions getvisualstyle () { case "$os" in "Windows XP") ;; "Windows"*) path="/proc/registry/HKEY_CURRENT_USER/Software/Microsoft" path+="/Windows/CurrentVersion/Themes/CurrentTheme" visualstyle="$(head -n1 $path)" visualstyle="${visualstyle##*\\}" visualstyle="${visualstyle%.*}" visualstyle="${visualstyle^}" ;; *) visualstyle="This feature only works on Windows" ;; esac } # }}} # Images {{{ getwallpaper () { case "$os" in "Linux") img="$(awk -F\' '/feh/ {printf $2}' $HOME/.fehbg)" ;; "Windows") case "$distro" in "Windows XP") img="/cygdrive/c/Documents and Settings/${USER}" img+="/Local Settings/Application Data/Microsoft" img+="/Wallpaper1.bmp" ;; "Windows"*) img="$APPDATA/Microsoft/Windows/Themes" img+="/TranscodedWallpaper.jpg" ;; esac ;; esac } getshuffle () { # TODO: Test this on Windows. img="$(find $shuffledir -type f \( -name '*.jpg' -o -name '*.png' \) -print0 | shuf -n1 -z)" } getimage () { # Make the directory if it doesn't exist mkdir -p "$imgtempdir" # Image size is half of the terminal imgsize=$((columns * font_width / split_size)) # Where to draw the image case "$image_position" in "left") # Padding is half the terminal width + gap padding="\e[$((columns / split_size + gap))C" ;; "right") padding="\e[0C" xoffset=$((columns * font_width / split_size - gap)) ;; esac # If wall=on, Get image to display from current wallpaper. case "$image" in "wall") getwallpaper ;; "shuffle") getshuffle ;; *) img="$image" ;; esac # Get name of image and prefix it with it's crop mode and offset imgname="$crop_mode-$crop_offset-$imgsize-${img##*/}" # Check to see if the thumbnail exists before we do any cropping. if [ ! -f "$imgtempdir/$imgname" ]; then # Get image size so that we can do a better crop size=$(identify -format "%w %h" "$img") width=${size%% *} height=${size##* } # This checks to see if height is geater than width # so we can do a better crop of portrait images. if [ $height -gt $width ]; then size=$width else size=$height fi case "$crop_mode" in fit) c=$(convert "$img" \ -colorspace srgb \ -format "%[pixel:p{0,0}]" info:) convert \ "$img" \ -trim +repage \ -gravity south \ -background "$c" \ -extent "$size"x"$size" \ -scale "$imgsize"x"$imgsize" \ "$imgtempdir/$imgname" ;; fill) convert \ "$img" \ -trim +repage \ -scale "$imgsize"x"$imgsize"^ \ -extent "$imgsize"x"$imgsize" \ "$imgtempdir/$imgname" ;; *) convert \ "$img" \ -gravity $crop_offset \ -crop "$size"x"$size"+0+0 \ -quality 95 \ -scale "$imgsize"x"$imgsize" \ "$imgtempdir/$imgname" ;; esac fi # The final image img="$imgtempdir/$imgname" } takescrot () { $scrotcmd "$scrotdir/$scrotname" } # }}} # Text Formatting {{{ underline () { underline=$(printf %"$length"s) underline=${underline// /$underline_char} } colors () { title_color="\e[38;5;${title_color}m" subtitle_color="\e[38;5;${subtitle_color}m" colon_color="\e[38;5;${colon_color}m" underline_color="\e[38;5;${underline_color}m" info_color="\e[38;5;${info_color}m" } bold () { if [ "$bold" == "on" ]; then bold="\e[1m" else bold="" fi } clear="\e[0m" # }}} # Usage {{{ usage () { cat << EOF usage: ${0##*/} [--colors 1 2 3 4 5] [--kernel "\$\(uname -rs\)"] Info: --title string Change the title at the top --distro string/cmd Manually set the distro --kernel string/cmd Manually set the kernel --uptime string/cmd Manually set the uptime --uptime_shorthand on/off --v Shorten the output of uptime --packages string/cmd Manually set the package count --shell string/cmd Manually set the shell --winman string/cmd Manually set the window manager --use_wmctrl on/off Use wmctrl for a more accurate reading --cpu string/cmd Manually set the cpu name --memory string/cmd Manually set the memory --speed_type Change the type of cpu speed to get Possible values: current, min, max --song string/cmd Manually set the current song Text Colors: --colors 1 2 3 4 5 Change the color of text (title, subtitle, colon, underline, info) --title_color num Change the color of the title --subtitle_color num Change the color of the subtitle --colon_color num Change the color of the colons --underline_color num Change the color of the underlines --info_color num Change the color of the info Text Formatting: --underline on/off Enable/Disable title underline --underline_char char Character to use when underlineing title --line_wrap on/off Enable/Disable line wrapping --bold on/off Enable/Disable bold text --prompt_height num Set this to your prompt height to fix issues with the text going off screen at the top Color Blocks: --color_blocks on/off Enable/Disable the color blocks --block_width num Width of color blocks --block_range start end --v Range of colors to print as blocks Image: --image Image source. Where and what image we display. Possible values: wall, shuffle, /path/to/img, off --shuffledir Which directory to shuffle for an image. --font_width px Used to automatically size the image --image_position Where to display the image: (Left/Right) --split_size num Width of img/text splits A value of 2 makes each split half the terminal width and etc --crop_mode Which crop mode to use Takes the values: normal, fit, fill --crop_offset value Change the crop offset for normal mode. Possible values: northwest, north, northeast, west, center, east, southwest, south, southeast --xoffset px How close the image will be to the left edge of the window --yoffset px How close the image will be to the top edge of the window --gap num Gap between image and text right side to the top edge of the window --clean Remove all cropped images Screenshot: --scrot Take a screenshot --scrotdir Directory to save the scrot --scrotfile File name of scrot --scrotcmd Screenshot program to launch Other: --help Print this text and exit EOF exit 1 } # }}} # Args {{{ while [ "$1" ]; do case $1 in # Info --title) title="$2" ;; --os) os="$2" ;; --kernel) kernel="$2" ;; --uptime) uptime="$2" ;; --uptime_shorthand) uptime_shorthand="$2" ;; --packages) packages="$2" ;; --shell) shell="$2" ;; --winman) windowmanager="$2" ;; --use_wmctrl) use_wmctrl="$2" ;; --cpu) cpu="$2" ;; --speed_type) speed_type="$2" ;; --memory) memory="$2" ;; --song) song="$2" ;; # Text Colors --colors) title_color=$2 [ "$3" ] && subtitle_color=$3 [ "$4" ] && colon_color=$4 [ "$4" ] && underline_color=$5 [ "$5" ] && info_color=$6 ;; --title_color) title_color=$2 ;; --subtitle_color) subtitle_color=$2 ;; --colon_color) colon_color=$2 ;; --underline_color) underline_color=$2 ;; --info_color) info_color=$2 ;; # Text Formatting --underline) underline="$2" ;; --underline_char) underline_char="$2" ;; --line_wrap) line_wrap="$2" ;; --bold) bold="$2" ;; --prompt_height) prompt_height="$2" ;; # Color Blocks --color_blocks) color_blocks="$2" ;; --block_range) start=$2; end=$3 ;; --block_width) block_width="$2" ;; # Image --image) image="$2" ;; --shuffledir) shuffledir="$2" ;; --font_width) font_width="$2" ;; --image_position) image_position="$2" ;; --split_size) split_size="$2" ;; --crop_mode) crop_mode="$2" ;; --crop_offset) crop_offset="$2" ;; --xoffset) xoffset="$2" ;; --yoffset) yoffset="$2" ;; --gap) gap="$2" ;; --clean) rm -rf "$imgtempdir" || exit ;; # Screenshot --scrot|-s) scrot="on" ;; --scrotdir) scrot="$2" ;; --scrotfile) scrot="$2" ;; --scrotcmd) scrot="$2" ;; # Other --help) usage ;; esac shift done # }}} # Print Info {{{ printinfo () { for info in "${info[@]}"; do function=${info#*: } subtitle=${info%:*} case "$info" in echo:*:*) info=${function#*: } subtitle=${function/:*/} string="${bold}${subtitle_color}${subtitle}${clear}" string+="${colon_color}: ${info_color}${info}" length=${#function} ;; echo:*) string="${info_color}${function}" length=${#function} ;; title:*) string="${bold}${title_color}${function}" length=${#function} ;; linebreak) string="" ;; underline) if [ "$underline" == "on" ]; then underline string="${underline_color}${underline}" fi ;; *:*|*) # Update the var var=${function/get/} typeset -n output=$var # Call the function [ -z "$output" ] && $function ;;& gettitle) string="${bold}${title_color}${output}" length=${#output} ;; *:*) string="${bold}${subtitle_color}${subtitle}${clear}" string+="${colon_color}: ${info_color}${output}" length=$((${#subtitle} + ${#output} + 2)) ;; *) string="$output" length=${#output} ;; esac printf "%b%s\n" "${padding}${string}${clear}" done } # }}} # Call Functions and Finish Up {{{ # Get lines and columns termsize=$(printf "lines \n cols" | tput -S) termsize=${termsize/$'\n'/ } lines=${termsize% *} columns=${termsize#* } # Get image [ "$image" != "off" ] && getimage # Clear the terminal and hide the cursor printf "\e[?25l" clear # Disable line wrap [ "$line_wrap" == "off" ] && printf '\e[?7l' # Call functions and display info colors bold printinfo # Display the image [ "$image" != "off" ] && \ printf "%b%s" "0;1;$xoffset;$yoffset;$imgsize;$imgsize;;;;;$img\n4;\n3;" |\ $w3m_img_path # Enable line wrap again [ "$line_wrap" == "off" ] && printf '\e[?7h' # Move cursor to bottom and redisplay it. printf "%b%s" "\e[${lines}H\e[${prompt_height}A\e[?25h" # If enabled take a screenshot [ "$scrot" == "on" ] && takescrot # }}}