1#!/usr/local/bin/zsh 2# 3# NAME: 4# reporter 5# 6# SYNOPSIS: 7# reporter [all | aliases | bindings | completion | functions | 8# limits | options | variables | zstyles] 9# 10# DESCRIPTION: 11# "reporter" prints your current environment variables, shell 12# variables, limits, completion settings, and option settings to 13# stdout in the form of a script. 14# 15# If you run into a zsh bug, someone can source the output script to 16# recreate most of the environment under which you were working. 17# 18# IMPORTANT: "source" this script, don't try to run it directly. 19# Otherwise it won't report the settings for your 20# current shell session. 21# 22# OPTIONS: 23# All command-line options can be abbreviated. 24# 25# "aliases" prints only aliases. 26# "bindings" prints only "bindkey" commands. 27# "completion" prints only "compctl" commands. 28# "functions" prints "autoload" commands or actual functions. 29# "limits" prints "limit" commands for things like cputime, etc. 30# "modules" prints "zmodload" commands. 31# "options" prints "setopt" commands. 32# "variables" prints both shell and environment variables. 33# "zstyles" prints "zstyle" commands 34# 35# "all" tries to find every useful setting under your shell. 36# This is the default, and it's the same as typing all 37# of the above options on the command line. 38# 39# CAVEATS: 40# Assumes that you have the following programs in your search path: 41# awk, cut, echo, grep, sed, sort 42# Assumes that your C preprocessor lives in /lib/cpp or /usr/ccs/lib/cpp. 43# Uses (and unsets) variables beginning with "reporter_". 44# Won't work for versions of zsh that are older than 3.1.3 or so. 45# 46# RESTRICTIONS: 47# DON'T: pretend you wrote it, sell it, or blame me if it breaks. 48# DO: as ye will an' ye harm none. 49# --Wiccan saying, I think 50# 51# BUGS: 52# I'm sure there are more than a few. To be safe, run "zsh -f" before 53# sourcing the output from this script. If you have "screen", you may 54# want to use that, too; I hammered my terminal settings beyond repair 55# when using an early version, and "screen" saved me from having to 56# login on another terminal. 57# 58# HISTORY: 59# The name was ripped off from the Emacs "reporter.el" function. 60# The idea came from a mail message to the ZSH mailing list: 61# 62# Begin Configuration Section 63# 64 65reporter_OSVersion="`uname -s`_`uname -r`" 66 67# 68# Solaris 2.x 69# 70case ${reporter_OSVersion} in 71 SunOS_5.*) 72 CPP=${CPP:-/usr/ccs/lib/cpp} 73 AWK=${AWK:-nawk} # GNU AWK doesn't come standard :-( 74 ;; 75esac 76 77# 78# Default Values 79# 80 81CPP=${CPP:-/lib/cpp} 82AWK=${AWK:-awk} 83 84# 85# End Configuration Section 86# 87 88reporter_do_all=yes 89 90for reporter_each 91do 92 case "$reporter_each" 93 in 94 ali*) reporter_do_aliases=yes; reporter_do_all=no ;; 95 b*) reporter_do_bindings=yes; reporter_do_all=no ;; 96 c*) reporter_do_compctl=yes; reporter_do_all=no ;; 97 f*) reporter_do_fun=yes; reporter_do_all=no ;; 98 l*) reporter_do_lim=yes; reporter_do_all=no ;; 99 m*) reporter_do_mod=yes; reporter_do_all=no ;; 100 o*) reporter_do_setopt=yes; reporter_do_all=no ;; 101 v*) reporter_do_vars=yes; reporter_do_all=no ;; 102 zs*|s*) reporter_do_zstyle=yes; reporter_do_all=no ;; 103 *) ;; 104 esac 105done 106 107# 108# The "cshjunkiequotes" option can break some of the commands 109# used in the remainder of this script, so we check for that first 110# and disable it. Similarly "shwordsplit" and "kshoptionprint". 111# We'll re-enable them later. 112# 113 114reporter_junkiequotes="no" 115reporter_shwordsplit="no" 116reporter_kshoptprint="no" 117reporter_nounset="no" 118 119if [[ -o cshjunkiequotes ]] 120then 121 reporter_junkiequotes="yes" 122 unsetopt cshjunkiequotes 123fi 124if [[ -o shwordsplit ]] 125then 126 reporter_shwordsplit="yes" 127 unsetopt shwordsplit 128fi 129if [[ -o kshoptionprint ]] 130then 131 reporter_kshoptprint="yes" 132 unsetopt kshoptionprint 133fi 134if [[ -o nounset ]] 135then 136 reporter_nounset="yes" 137 unsetopt nounset 138fi 139 140# 141# UNAME 142# 143# This shows your system name. It's extremely system-dependent, so 144# we need a way to find out what system you're on. The easiest 145# way to do this is by using "uname", but not everyone has that, 146# so first we go through the search path. 147# 148# If we don't find it, then the only thing I can think of is to 149# check what's defined in your C compiler, and code in some exceptions 150# for the location of "uname" or an equivalent. For example, Pyramid 151# has "uname" only in the ATT universe. This code assumes that 152# the "-a" switch is valid for "uname". 153# 154# This section of code sees what is defined by "cpp". It was 155# originally written by brandy@tramp.Colorado.EDU (Carl Brandauer). 156# Additional error checking and sed hacking added by Ken Phelps. 157# 158 159reporter_cppdef=(`strings -3 ${CPP} | 160 sed -n ' 161 /^[a-zA-Z_][a-zA-Z0-9_]*$/{ 162 s/.*/#ifdef &/p 163 s/.* \(.*\)/"\1";/p 164 s/.*/#endif/p 165 } 166 ' | ${CPP} |sed ' 167 /^[ ]*$/d 168 /^#/d 169 s/.*"\(.*\)".*/\1/'`) 170 171reporter_uname="" 172 173for reporter_each in `echo $PATH | sed -e 's/:/ /g'` 174do 175 if [[ -x $reporter_each/uname ]] 176 then 177 reporter_uname="$reporter_each/uname" 178 break 179 fi 180done 181 182case "$reporter_uname" 183in 184 "") reporter_uname="echo not found on this system" ;; 185 *) ;; 186esac 187 188for reporter_each in $reporter_cppdef 189do 190 case "$reporter_each" 191 in 192 pyr) reporter_uname="/bin/att uname" ;; 193 *) ;; 194 esac 195done 196 197echo '# START zsh saveset' 198echo '# uname: ' `eval $reporter_uname -a` 199echo 200 201unset reporter_cppdef 202unset reporter_uname 203unset reporter_each 204 205# 206# ALIASES 207# 208# Use "alias -L" to get a listing of the aliases in the form we want. 209# 210 211if [[ "$reporter_do_all" = "yes" || "$reporter_do_aliases" = "yes" ]] 212then 213 echo '# Aliases.' 214 echo 215 216 alias -L 217fi 218 219# 220# KEY BINDINGS 221# 222# The -L option does most of the work. The subshell is used to 223# avoid modifying things that will be recorded later. 224# 225 226if [[ "$reporter_do_all" = "yes" || "$reporter_do_bindings" = "yes" ]] 227then 228 echo 229 echo "# Key bindings." 230 echo 231 bindkey -lL | grep -v ' \.safe$' 232 ( 233 alias bindkey=bindkey 234 bindkey () { 235 [[ "$1" == "-N" ]] || return 236 [[ "$2" == "--" ]] && shift 237 [[ "$2" == ".safe" ]] && return 238 echo 239 builtin bindkey -L -M -- "$2" 240 } 241 eval "`builtin bindkey -lL`" 242 ) 243fi 244 245# 246# COMPLETION COMMANDS 247# Warning: this won't work for zsh-2.5.03. 248# 249 250if [[ "$reporter_do_all" = "yes" || "$reporter_do_compctl" = "yes" ]] 251then 252 echo 253 echo "# Completions." 254 echo 255 256 compctl -L 257fi 258 259# 260# FUNCTIONS 261# 262 263if [[ "$reporter_do_all" = "yes" || "$reporter_do_fun" = "yes" ]] 264then 265 echo 266 echo "# Undefined functions." 267 echo 268 269 autoload + | ${AWK} '{print "autoload " $1}' 270 271 echo 272 echo "# Defined functions." 273 echo 274 275 ( 276 unfunction `autoload +` 2>/dev/null 277 functions 278 ) 279fi 280 281# 282# LIMITS 283# 284# "cputime" has to be handled specially, because you can specify 285# the time as just hours, or "minutes:seconds". 286# 287 288if [[ "$reporter_do_all" = "yes" || "$reporter_do_lim" = "yes" ]] 289then 290 echo 291 echo '# Limits.' 292 echo 293 294 ( 295 set X `limit | grep "cputime" | grep -v "unlimited" | 296 sed -e 's/:/ /g'` 297 298 if test "$#" -gt 1 299 then 300 hr=$3 301 min=$4 302 sec=$5 303 304 if test "$hr" -gt 0 305 then 306 echo "limit cputime ${hr}h" 307 else 308 echo "limit cputime $min:$sec" 309 fi 310 fi 311 ) 312 313 limit | grep -v "cputime" | grep -v "unlimited" | 314 sed -e 's/Mb/m/' -e 's/Kb/k/' | 315 ${AWK} 'NF > 1 {print "limit " $0}' 316fi 317 318# 319# MODULE LOADING COMMANDS 320# 321 322if [[ "$reporter_do_all" = "yes" || "$reporter_do_mod" = "yes" ]] 323then 324 echo 325 if ( zmodload ) >& /dev/null; then 326 echo "# Modules." 327 echo 328 zmodload -d -L 329 echo 330 zmodload -ab -L 331 echo 332 zmodload -ac -L 333 echo 334 zmodload -ap -L 335 echo 336 zmodload -L 337 else 338 echo "# Modules: zmodload not available." 339 fi 340fi 341 342# 343# NON-ARRAY VARIABLES 344# 345# We run this in a subshell to preserve the parameter module state 346# in the current shell. Also, reset the prompt to show you're now 347# in a test shell. 348# 349 350if [[ "$reporter_do_all" = "yes" || "$reporter_do_vars" = "yes" ]] 351then 352 echo 353 echo "# Non-array variables." 354 echo 355 356 ( 357 zmodload -u `zmodload | grep parameter` 2>/dev/null 358 359 echo "ARGC=0" 360 eval `typeset + | 361 grep -v 'array ' | 362 grep -v 'association ' | 363 grep -v 'undefined ' | 364 grep -v ' ARGC$' | 365 grep -v '^reporter_' | 366 grep -wv '[!#$*0?@_-]$' | 367 sed -e 's/.* \(.*\)/print -r -- \1=${(qq)\1};/' \ 368 -e 's/^\([^ ]*\)$/print -r -- \1=${(qq)\1};/'` 369 echo "prompt='test%'" 370 ) 371 372# 373# ARRAY VARIABLES 374# 375# Run this in a subshell to preserve the parameter module state in 376# the current shell. 377# 378 379 echo 380 echo "# Array variables." 381 echo 382 383 ( 384 zmodload -u `zmodload | grep parameter` 2>/dev/null 385 386 echo "argv=()" 387 eval `{ typeset + | grep 'array ' ; 388 typeset + | grep 'association ' } | 389 grep -v 'undefined ' | 390 grep -v ' argv$' | 391 grep -v ' reporter_' | 392 grep -v ' [!#$*0?@_-]$' | 393 sed 's/.* \(.*\)/print -r -- \1=\\\(${(qq)\1}\\\);/'` 394 ) 395 396# 397# EXPORTED VARIABLES 398# 399# Run this in a subshell to preserve the parameter module state in 400# the current shell. 401# 402 403 echo 404 echo "# Exported variables." 405 echo 406 407 ( 408 zmodload -u `zmodload | grep parameter` 2>/dev/null 409 410 export | grep -v "^'*"'[!#$*0?@_-]'"'*=" | 411 ${AWK} -F'=' '{print "export " $1}' 412 ) 413fi 414 415# 416# SETOPT 417# 418# We exclude interactive because "setopt interactive" has no effect. 419# A few special options are dealt with separately; see the comments 420# near the start of the script. 421# 422 423if [[ "$reporter_do_all" = "yes" || "$reporter_do_setopt" = "yes" ]] 424then 425 echo 426 echo '# Setopt.' 427 echo 428 429 ( 430 setopt | grep -v 'interactive' | ${AWK} '{print "setopt " $0}' 431 432 case "$reporter_junkiequotes" 433 in 434 yes) echo "setopt cshjunkiequotes" ;; 435 *) ;; 436 esac 437 case "$reporter_shwordsplit" 438 in 439 yes) echo "setopt shwordsplit" ;; 440 *) ;; 441 esac 442 case "$reporter_kshoptprint" 443 in 444 yes) echo "setopt kshoptionprint" ;; 445 *) ;; 446 esac 447 case "$reporter_nounset" 448 in 449 yes) echo "setopt nounset" ;; 450 *) ;; 451 esac 452 ) | sort 453fi 454 455# 456# STYLES 457# 458 459if [[ "$reporter_do_all" = "yes" || "$reporter_do_zstyle" = "yes" ]] 460then 461 echo 462 echo '# Styles.' 463 echo 464 465 zstyle -L 466fi 467 468echo 469echo '# END zsh saveset' 470 471# 472# Don't put an exit here, or you'll get a nasty surprise when you 473# source this thing. Get rid of variables created when processing 474# command line. 475# 476 477unset reporter_do_all 478unset reporter_do_aliases 479unset reporter_do_bindings 480unset reporter_do_compctl 481unset reporter_do_fun 482unset reporter_do_lim 483unset reporter_do_setopt 484unset reporter_do_vars 485 486# 487# Turn various options back on if necessary, in case run via ".". 488# 489 490case "$reporter_junkiequotes" 491in 492 yes) setopt cshjunkiequotes ;; 493 *) ;; 494esac 495case "$reporter_shwordsplit" 496in 497 yes) setopt shwordsplit ;; 498 *) ;; 499esac 500case "$reporter_kshoptprint" 501in 502 yes) setopt kshoptionprint ;; 503 *) ;; 504esac 505case "$reporter_nounset" 506in 507 yes) setopt nounset ;; 508 *) ;; 509esac 510 511unset reporter_junkiequotes 512unset reporter_shwordsplit 513unset reporter_kshoptprint 514unset reporter_nounset 515 516unset reporter_OSVersion 517