فایل ~/.bashrc رفتار پوستههای محاورهای را تعیین میکند. یک نگاه شایسته به این فایل میتواند منجر به درک بهتری از Bash بشود.
Emmanuel Rouat فایل .bashrc دارای جزییات بسیار زیاد پایین، نوشته شده برای یک سیستم لینوکس را اهدا نموده است.
فایل را به دقت مطالعه کنید، و با خیال راحت قطعه کدها و توابع آن را در فایل .bashrc خودتان یا حتی در اسکریپتهایتان استفاده نمایید.
مثال M-1. فایل نمونه .bashrc
#================================================================ # # #فایل شخصی $HOME/.bashrc برای bash-3.0 (یا بعد از آن) #توسط Emmanuel Rouat [no-email] # #آخرین ویرایش: Tue Nov 20 22:04:47 CET 2012 #این فایل به طور عادی فقط به وسیله پوستههای محاورهای خوانده میشود. #+محلی است که مستعارها، توابع و سایر ویژگیهای محاورهای مانند اعلان #+فرمان پوسته شما تعریف میشوند. # #بیشتر کد مندرج در آن فرض میکند که شما روی یک سیستم گنو (به احتمال #+بسیار یک Linux box) هستید و اکثر بخشهای آن بر اساس کدهای مشاهده #+شده در Usenet یا اینترنت است. # #برای نمونه موارد زیر را ببینید: # # # # # #انتخاب رنگها برای یک پوسته با پسزمینه تاریک (سفید روی سیاه) انجام #+شده است، و این معمولاً برای وضعیت متن خالص کنسولها (نه سرویسدهنده #+X موجود) نیز مناسب است. اگر شما از پسزمینه سفید استفاده میکنید، #+برای خوانایی بهتر باید انتخابهای دیگری به عمل آورید. # #این فایل bashrc کمی زیادی شلوغ است. #به خاطر داشته باشید که فقط فقط یک مثال است. به تناسب نیازهای خود #آن را ویرایش نمایید. # #================================================================= # #-->توضیحات اضافه شده به وسیله نویسنده HOWTO. #اگر در وضعیت محاورهای اجرا نشود، کاری انجام نمیدهد [ -z "$PS1" ] && return #------------------------------------------------------------- #منبع کردن تعاریف سراسری (اگر موجود باشد) #------------------------------------------------------------- if [ -f /etc/bashrc ]; then . /etc/bashrc # -->خواندن فایل /etc/bashrc اگر باشد. fi #-------------------------------------------------------------- #تنظیم خوکار $DISPLAY (اگر از قبل تنظیم نباشد). #این برای من کار میکند - در مورد شما ممکن است متفاوت باشد . . . #مشکل آن است که انواع متفاوت ترمینال پاسخهای مختلفی به who am i #+میدهند (مخصوصا rxvt میتواند دردسر آفرین باشد) - به هر حال این #+کد ظاهراً با اکثریت موارد کار میکند. #-------------------------------------------------------------- function get_xserver () { case $TERM in xterm ) XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) #Ane-Pieter Wieringa جایگزین زیر را پیشنهاد میکند: # # # XSERVER=${XSERVER%%:*} ;; aterm | rxvt) #مقداری کد بیابید که در اینجا کار کند. ... ;; esac } if [ -z ${DISPLAY:=""} ]; then get_xserver if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) || ${XSERVER} == "unix" ]]; then DISPLAY=":0.0" #Display روی میزبان محلی. else DISPLAY=${XSERVER}:0.0 #Display روی میزبان راه دور. fi fi export DISPLAY #-------------------------------------------------------------- #برخی تنظیمات #-------------------------------------------------------------- # #اینها دو انتخاب مفید برای اشکالزدابی هستند. # alias debug="set -o nounset; set -o xtrace" ulimit -S -c 0 #تهیه فایلهای core (رونوشت حافظه) لازم نیست. set -o notify set -o noclobber set -o ignoreeof #فعال کردن گزینهها: shopt -s cdspell shopt -s cdable_vars shopt -s checkhash shopt -s checkwinsize shopt -s sourcepath shopt -s no_empty_cmd_completion shopt -s cmdhist shopt -s histappend histreedit histverify shopt -s extglob #برای تکمیل قابل برنامهریزی لازم است. #از کار انداختن گزینهها: shopt -u mailwarn unset MAILCHECK #لازم نیست پوسته mail وارده را اطلاع بدهد. #-------------------------------------------------------------- #پیغام خوشامدگویی، و غیره ... #-------------------------------------------------------------- #تعاریف رنگ (بر گرفته از اعلان Bash رنگی در HowTo). #برخی رنگها ممکن است در ترمینالها متفاوت دیده شوند. #برای مثال، من قرمز ضخیم را در نمایشگرم نارنجی میبینم #از اینرو اغلب توالی Green، BRed، Red را در اعلانم به کار میبرم. #رنگهای عادی Black='\e[0;30m' #سیاه Red='\e[0;31m' #قرمز Green='\e[0;32m' #سبز Yellow='\e[0;33m' #زرد Blue='\e[0;34m' #آبی Purple='\e[0;35m' #زرشکی Cyan='\e[0;36m' #فیروزهای White='\e[0;37m' #سفید #ضخیم BBlack='\e[1;30m' #سیاه BRed='\e[1;31m' #قرمز BGreen='\e[1;32m' #سبز BYellow='\e[1;33m' #زرد BBlue='\e[1;34m' #آبی BPurple='\e[1;35m' #زرشکی BCyan='\e[1;36m' #فیروزهای BWhite='\e[1;37m' #سفید #پسزمینه On_Black='\e[40m' #سیاه On_Red='\e[41m' #قرمز On_Green='\e[42m' #سبز On_Yellow='\e[43m' #زرد On_Blue='\e[44m' #آبی On_Purple='\e[45m' #زرشکی On_Cyan='\e[46m' #فیروزهای On_White='\e[47m' #سفید NC="\e[m" #بازنشانی رنگ ALERT=${BWhite}${On_Red} #سفید ضخیم روی پسزمینه قرمز echo -e "${BCyan}This is BASH ${BRed}${BASH_VERSION%.*}${BCyan}\ - DISPLAY on ${BRed}$DISPLAY${NC}\n" date if [ -x /usr/games/fortune ]; then /usr/games/fortune -s #روزمان را قدری مفرحتر میکند.... :-) fi function _exit() #تابعی جهت اجرا به محض خروج از پوسته { echo -e "${BRed}Hasta la vista, baby${NC}" } trap _exit EXIT #------------------------------------------------------------- #اعلان پوسته - برای نمونههای زیاد، موارد زیر را ببینید: #http://www.debian-administration.org/articles/205 #http://www.askapache.com/linux/bash-power-prompt.html #http://tldp.org/HOWTO/Bash-Prompt-HOWTO #https://github.com/nojhan/liquidprompt #------------------------------------------------------------- # # #سبز == بارگیری ماشین پایین است #نارنجی == بارگیری ماشین متوسط است #قرمز == بارگیری ماشین بالاست #سفید روی قرمز == بارگیری خیلی بالاست # #فیروزهای == کاربر عادی #نارنجی == SU به کاربر #قرمز == کاربر root # #فیروزهای == نشست محلی #سبز == اتصال راهدور امن(از طریق ssh) #قرمز == اتصال راه دور نا امن # #سبز == فضای خالی بیش از 10% دیسک #نارنجی == فضای خالی کمتر از 10% دیسک #سفید روی قرمز == فضای خالی کمتر از 5% دیسک #قرمز == کاربر جاری فاقد امتیاز نوشتن است #فیروزهای == اندازه سیستم فایل جاری صفر است (مانند /proc) # #سفید == هیچ job پسزمینه یا تعلیقی در این پوسته نیست #فیروزهای == حداقل یک job پسزمینه در این پوسته هست #نارنجی == حداقل یک job تعلیقی در این پوسته هست # #وقتی شما اینتر را بزنید فرمان به فایل تاریخچه اضافه میشود #پس برای تمام پوستهها معتبر است (با استفاده از history -a). #تست نوع ارتباط: if [ -n "${SSH_CONNECTION}" ]; then CNX=${Green} #متصل روی ماشین راه دور (از طریق ssh) (خوب). elif [[ "${DISPLAY%%:0*}" != "" ]]; then CNX=${ALERT} #متصل در ماشین راه دور ، نه از طریق ssh (بد). else CNX=${BCyan} #متصل روی ماشین محلی. fi #تست نوع کاربر: if [[ ${USER} == "root" ]]; then SU=${Red} #کاربر root است. elif [[ ${USER} != $(logname) ]]; then SU=${BRed} #کاربر، یک کاربر لاگین نیست. else SU=${BCyan} #کاربر عادی (خب، اکثر ما هستیم). fi NCPU=$(grep -c 'processor' /proc/cpuinfo) #تعداد CPU SLOAD=$(( 100*${NCPU} )) #بارگیری آهسته MLOAD=$(( 200*${NCPU} )) #بارگیری متوسط XLOAD=$(( 400*${NCPU} )) #بارگیری خیلی زیاد #بارگیری سیستم را برحسب درصد برگشت میدهد، مثلاً 40 به جای 0.40 function load() { local SYSLOAD=$(cut -d " " -f1 /proc/loadavg | tr -d '.') #بارگیری سیستم میزبان جاری. echo $((10#$SYSLOAD)) #تبدیل به دسیمال. } #یک رنگ نشاندهنده بارگیری سیستم برگشت میدهد. function load_color() { local SYSLOAD=$(load) if [ ${SYSLOAD} -gt ${XLOAD} ]; then echo -en ${ALERT} elif [ ${SYSLOAD} -gt ${MLOAD} ]; then echo -en ${Red} elif [ ${SYSLOAD} -gt ${SLOAD} ]; then echo -en ${BRed} else echo -en ${Green} fi } #یک رنگ متناسب با فضای خالی دیسک در $PWD برگشت میدهد. function disk_color() { if [ ! -w "${PWD}" ] ; then echo -en ${Red} #فاقد امتیاز نوشتن در دایرکتوری جاری است. elif [ -s "${PWD}" ] ; then local used=$(command df -P "$PWD" | awk 'END {print $5} {sub(/%/,"")}') if [ ${used} -gt 95 ]; then echo -en ${ALERT} #دیسک تقریبا پُر است (>95%). elif [ ${used} -gt 90 ]; then echo -en ${BRed} #فضای خالی دیسک تقریبا تمام شده. else echo -en ${Green} #فضای خالی دیسک مناسب است. fi else echo -en ${Cyan} #اندازه دایرکتوری جاری صفر است (مانند /proc، /sys و غیره). fi } #متناسب با jobهای در حال اجرا یا معلق، یک رنگ برگشت میدهد. function job_color() { if [ $(jobs -s | wc -l) -gt "0" ]; then echo -en ${BRed} elif [ $(jobs -r | wc -l) -gt "0" ] ; then echo -en ${BCyan} fi } #مقداری متن به کالبد ترمینال اضافه میکند (اگر شدنی باشد). #اکنون ما اعلان را ایجاد میکنیم. PROMPT_COMMAND="history -a" case ${TERM} in *term | rxvt | linux) PS1="\[\$(load_color)\][\A\[${NC}\] " #ساعت (با اطلاعات بارگیری): PS1="\[\$(load_color)\][\A\[${NC}\] " #User@Host (با اطلاعات نوع ارتباط): PS1=${PS1}"\[${SU}\]\u\[${NC}\]@\[${CNX}\]\h\[${NC}\] " #PWD (با اطلاعات فضای خالی دیسک): PS1=${PS1}"\[\$(disk_color)\]\W]\[${NC}\] " #اعلان (با اطلاعات job): PS1=${PS1}"\[\$(job_color)\]>\[${NC}\] " #تنظیم عنوان xterm جاری: PS1=${PS1}"\[\e]0;[\u@\h] \w\a\]" ;; *) PS1="(\A \u@\h \W) > " # --> # -->نام مسیر کامل شاخه جاری را نمایش میدهد. ;; esac export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n' export HISTIGNORE="&:bg:fg:ll:h" export HISTTIMEFORMAT="$(echo -e ${BCyan})[%d/%m %H:%M:%S]$(echo -e ${NC}) " export HISTCONTROL=ignoredups export HOSTFILE=$HOME/.hosts #لیستی از میزبانهای راه دور در ~/.hosts قرار بدهید #============================================================ # #مستعارها و توابع # #شاید برخی از توابع تعریف شده در اینجا واقعاً بزرگ باشند. #اگر شما مایل هستید این فایل را کوچکتر کنید، میتوانید این #+توابع را به اسکریپت تبدیل نموده و از اینجا حذف نمایید. # #============================================================ #------------------- #مستعارهای شخصی #------------------- alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # ->از پاک کردن اتفاقی فایل پیشگیری میکند. alias mkdir='mkdir -p' alias h='history' alias j='jobs -l' alias which='type -a' alias ..='cd ..' #چاپ شکیل متغیرهای PATH: alias path='echo -e ${PATH//:/\\n}' alias libpath='echo -e ${LD_LIBRARY_PATH//:/\\n}' alias du='du -kh' #خروجی خواناتری تولید میکند. alias df='df -kTh' #----------------------------------------------------------------------- #خانواده ls (این مستعارها مبتنی بر استفاده از نگارش جدید ls گنو است). #----------------------------------------------------------------------- #افزودن رنگ برای نوع فایل و اندازههای خوانای فایل به خروجی ls: alias ls='ls -h --color' alias lx='ls -lXB' #مرتب کردن نسبت به پسوند فایلها. alias lk='ls -lSr' #مرتب کردن برحسب اندازه، بزرگترین در انتها. alias lt='ls -ltr' #مرتب نمودن به نسبت تاریخ، جدیدترین در انتها. alias lc='ls -ltcr' #مرتبسازی به نسبت زمان تغییر/،جدیدترین در انتها. alias lu='ls -ltur' #مرتب کردن به نسبت زمان دستیابی، جدیدترین در آخر. #ll همه جا حاضر: نخست دایرکتوریها، با مرتبسازی الفبایی: alias ll="ls -lv --group-directories-first" alias lm='ll |more' #لولهکشی به برنامه more alias lr='ll -R' #ls بازگشتی. alias la='ll -A' #نمایش فایلهای پنهان. alias tree='tree -Csuh' #جایگزین خوبی برای ls بازگشتی. #---------------------------------------------------------------- #مناسب نمودن less #---------------------------------------------------------------- alias more='less' export PAGER=less export LESSCHARSET='latin1' export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-' #استفاده از این در صورتیکه lesspipe.sh موجود است. export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \ :stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...' #رنگهای صفحه man فرمان less (صفحههای man را خواناتر میسازد). export LESS_TERMCAP_mb=$'\E[01;31m' export LESS_TERMCAP_md=$'\E[01;31m' export LESS_TERMCAP_me=$'\E[0m' export LESS_TERMCAP_se=$'\E[0m' export LESS_TERMCAP_so=$'\E[01;44;33m' export LESS_TERMCAP_ue=$'\E[0m' export LESS_TERMCAP_us=$'\E[01;32m' #------------------------------------------------------------- #اشتباهات تایپی - به شذت شخصی و مبتنی بر صفحه کلید :-) #------------------------------------------------------------- alias xs='cd' alias vf='cd' alias moer='more' alias moew='more' alias kk='ll' #------------------------------------------------------------- #چند مورد جالب #------------------------------------------------------------- #اضافه کردن مقداری متن به کالبد ترمینال (اگر مقدور باشد). function xtitle() { case "$TERM" in *term* | rxvt) echo -en "\e]0;$*\a" ;; *) ;; esac } #مستعارهایی که xtitle را به کار میبرند alias top='xtitle Processes on $HOST && top' alias make='xtitle Making $(basename $PWD) ; make' #.. و توابع function man() { for i ; do xtitle The $(basename $1|tr -d .[:digit:]) manual command man -a "$i" done } #------------------------------------------------------------- #خودکار سازی اجرا در پسزمینه برای فرمانهای زیر: #------------------------------------------------------------- function te() #بستهبندی در اطراف xemacs/gnuserv { if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then gnuclient -q "$@"; else ( xemacs "$@" &); fi } function soffice() { command soffice "$@" & } function firefox() { command firefox "$@" & } function xpdf() { command xpdf "$@" & } #------------------------------------------------------------- #توابع مرتبط بافایل و رشتهها: #------------------------------------------------------------- #جستجوی یک فایل با الگویی در نام: function ff() { find . -type f -iname '*'"$*"'*' -ls ; } #جستجوی یک فایل با الگوی $1 در نام و اجرای $2 روی آن: function fe() { find . -type f -iname '*'"${1:-}"'*' \ -exec ${2:-file} {} \; ; } #جستجوی یک الگو در یک مجموعه فایل و برجسته کردن آنها: #+(نیازمند نگارشهای جدید egrep است). function fstr() { OPTIND=1 local mycase="" local usage="fstr: find string in files. Usage: fstr [-i] \"pattern\" [\"filename pattern\"] " while getopts :it opt do case "$opt" in i) mycase="-i " ;; *) echo "$usage"; return ;; esac done shift $(( $OPTIND - 1 )) if [ "$#" -lt 1 ]; then echo "$usage" return; fi find . -type f -name "${2:-*}" -print0 | \ xargs -0 egrep --color=always -sn ${case} "$1" 2>&- | more } function swap() { #معاوضه نام دو فایل، اگر موجود باشند (از bashrc تنظیم Uzi). local TMPFILE=tmp.$$ [ $# -ne 2 ] && echo "swap: 2 arguments needed" && return 1 [ ! -e $1 ] && echo "swap: $1 does not exist" && return 1 [ ! -e $2 ] && echo "swap: $2 does not exist" && return 1 mv "$1" $TMPFILE mv "$2" "$1" mv $TMPFILE "$2" } function extract() #برنامه سودمند استخراج { if [ -f $1 ] ; then case $1 in *.tar.bz2) tar xvjf $1 ;; *.tar.gz) tar xvzf $1 ;; *.bz2) bunzip2 $1 ;; *.rar) unrar x $1 ;; *.gz) gunzip $1 ;; *.tar) tar xvf $1 ;; *.tbz2) tar xvjf $1 ;; *.tgz) tar xvzf $1 ;; *.zip) unzip $1 ;; *.Z) uncompress $1 ;; *.7z) 7z x $1 ;; *) echo "'$1' cannot be extracted via >extract<" ;; esac else echo "'$1' is not a valid file!" fi } #یک بایگانی (*.tar.gz) از دایرکتوری تعیین شده ایجاد میکند. function maketar() { tar cvzf "${1%%/}.tar.gz" "${1%%/}/"; } #یک بایگانی ZIP از یک فایل یا دایرکتوری تولید میکند. function makezip() { zip -r "${1%%/}.zip" "$1" ; } #دسترسی به فایلها و دایرکتوریهای شما را معقول میکند. function sanitize() { chmod -R u=rwX,g=rX,o= "$@" ;} #------------------------------------------------------------- #توابع مرتبط با Process/system: #------------------------------------------------------------- function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; } function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; } function killps() #kill به وسیله نام پردازش { local pid pname sig="-TERM" #سیگنال پیشفرض if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then echo "Usage: killps [-SIGNAL] pattern" return; fi if [ $# = 2 ]; then sig=$1 ; fi for pid in $(my_ps| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} ) do pname=$(my_ps | awk '$1~var { print $5 }' var=$pid ) if ask "Kill process $pid <$pname> with signal $sig?" then kill $sig $pid fi done } function mydf() #چاپ شکیل خروجی df { #ملهم از برنامه dfc for fs ; do if [ ! -d $fs ] then echo -e $fs" :No such file or directory" ; continue fi local info=( $(command df -P $fs | awk 'END{ print $2,$3,$5 }') ) local free=( $(command df -Pkh $fs | awk 'END{ print $4 }') ) local nbstars=$(( 20 * ${info[1]} / ${info[0]} )) local out="[" for ((j=0;j<20;j++)); do if [ ${j} -lt ${nbstars} ]; then out=$out"*" else out=$out"-" fi done out=${info[2]}" "$out"] ("$free" free on "$fs")" echo -e $out done } function my_ip() #به دست آوردن آدرس IP روی اترنت. { MY_IP=$(/sbin/ifconfig eth0 | awk '/inet/ { print $2 } ' | sed -e s/addr://) echo ${MY_IP:-"Not connected"} } function ii() #به دست آوردن اطلاعات مربوط به میزبان. { echo -e "\nYou are logged on ${BRed}$HOST" echo -e "\n${BRed}Additionnal information:$NC " ; uname -a echo -e "\n${BRed}Users logged on:$NC " ; w -hs | cut -d " " -f1 | sort | uniq echo -e "\n${BRed}Current date :$NC " ; date echo -e "\n${BRed}Machine stats :$NC " ; uptime echo -e "\n${BRed}Memory stats :$NC " ; free echo -e "\n${BRed}Diskspace :$NC " ; mydf / $HOME echo -e "\n${BRed}Local IP Address :$NC" ; my_ip echo -e "\n${BRed}Open connections :$NC "; netstat -pan --inet; echo } #------------------------------------------------------------- #برنامههای سودمند متفرقه: #------------------------------------------------------------- function repeat() #n مرتبه تکرار فرمان. { local i max max=$1; shift; for ((i=1; i <= max ; i++)); do # -->ترکیب دستوری سبک C eval "$@"; done } function ask() #برای مثال کاربرد آن، تابع killps را ببینید. { echo -n "$@" '[y/n] ' ; read ans case "$ans" in y*|Y*) return 0 ;; *) return 1 ;; esac } function corename() #کسب نام برنامه تولید کننده یک فایل core { for file ; do echo -n $file : ; gdb --core=$file --batch | head -1 done } #========================================================================= # #بخش تکمیل قابل برنامهریزی #بیشتر از مستندات bash 2.05 و از بسته «Bash completion» نوشته Ian McDonald #(http://www.caliban.org/bash/#completion) اخذ گردیده است #در واقع برای برخی ویژگیها شما به bash جدیدتر از نگارش 3.0 احتیاج دارید. # #توجه کنید که اکنون اکثر توزیعهای لینوکس تکمیلهای بسیاری را به طور آماده #ارایه میکنند - به هر حال ممکن است یک روز احتیاج داشته باشید خودتان آن را #انجام بدهید، بنابراین آنها را به عنوان نمونه در اینجا داشته باشید. #========================================================================= if [ "${BASH_VERSION%.*}" \< "3.0" ]; then echo "You will need to upgrade to version 3.0 for full \ programmable completion features" return fi shopt -s extglob #ضروری است. complete -A hostname rsh rcp telnet rlogin ftp ping disk complete -A export printenv complete -A variable export local readonly unset complete -A enabled builtin complete -A alias alias unalias complete -A function function complete -A user su mail finger complete -A helptopic help #به طور جاری مانند داخلیها. complete -A shopt shopt complete -A stopped -P '%' bg complete -A job -P '%' fg jobs disown complete -A directory mkdir rmdir complete -A directory -o default cd #فشردهسازی complete -f -o default -X '*.+(zip|ZIP)' zip complete -f -o default -X '!*.+(zip|ZIP)' unzip complete -f -o default -X '*.+(z|Z)' compress complete -f -o default -X '!*.+(z|Z)' uncompress complete -f -o default -X '*.+(gz|GZ)' gzip complete -f -o default -X '!*.+(gz|GZ)' gunzip complete -f -o default -X '*.+(bz2|BZ2)' bzip2 complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2 complete -f -o default -X '!*.+(zip|ZIP|z|Z|gz|GZ|bz2|BZ2)' extract #مستندات - Postscript، pdf، dvi..... complete -f -o default -X '!*.+(ps|PS)' gs ghostview ps2pdf ps2ascii complete -f -o default -X \ '!*.+(dvi|DVI)' dvips dvipdf xdvi dviselect dvitype complete -f -o default -X '!*.+(pdf|PDF)' acroread pdf2ps complete -f -o default -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?\ (.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf complete -f -o default -X '!*.tex' tex latex slitex complete -f -o default -X '!*.lyx' lyx complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps complete -f -o default -X \ '!*.+(doc|DOC|xls|XLS|ppt|PPT|sx?|SX?|csv|CSV|od?|OD?|ott|OTT)' soffice #چند رسانهای complete -f -o default -X \ '!*.+(gif|GIF|jp*g|JP*G|bmp|BMP|xpm|XPM|png|PNG)' xv gimp ee gqview complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321 complete -f -o default -X '!*.+(ogg|OGG)' ogg123 complete -f -o default -X \ '!*.@(mp[23]|MP[23]|ogg|OGG|wav|WAV|pls|\ m3u|xm|mod|s[3t]m|it|mtm|ult|flac)' xmms complete -f -o default -X '!*.@(mp?(e)g|MP?(E)G|wma|avi|AVI|\ asf|vob|VOB|bin|dat|vcd|ps|pes|fli|viv|rm|ram|yuv|mov|MOV|qt|\ QT|wmv|mp3|MP3|ogg|OGG|ogm|OGM|mp4|MP4|wav|WAV|asx|ASX)' xine complete -f -o default -X '!*.pl' perl perl5 #این یک تابع تکمیل همگانی است - وقتی کار میکند که فرمان دارای #+وضعیت «گزینههای بلند» یعنی: 'ls --all' به جای 'ls -a' باشد #به گزینه -o برای grep نیاز دارد #+(در صورتیکه معتبر نبود نگارش توضیحی شده آن را امتحان کنید). #اول = را از جداکنندههای کلمه تکمیل حذف کنید (این به تکمیلهایی #+مانند 'ls --color=auto' اجازه میدهد به طور صحیح کار کنند). COMP_WORDBREAKS=${COMP_WORDBREAKS/=/} _get_longopts() { # # $1 --help | grep -o -e "--[^[:space:].,]*" | grep -e "$2" |sort -u } _longopts() { local cur cur=${COMP_WORDS[COMP_CWORD]} case "${cur:-*}" in -*) ;; *) return ;; esac case "$1" in \~*) eval cmd="$1" ;; *) cmd="$1" ;; esac COMPREPLY=( $(_get_longopts ${1} ${cur} ) ) } complete -o default -F _longopts configure bash complete -o default -F _longopts wget id info a2ps ls recode _tar() { local cur ext regex tar untar COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} #اگر یک گزینه بخواهیم، گزینههای بلند محتمل برگشت داده میشوند. case "$cur" in -*) COMPREPLY=( $(_get_longopts $1 $cur ) ); return 0;; esac if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -W 'c t x u r d A' -- $cur ) ) return 0 fi case "${COMP_WORDS[1]}" in ?(-)c*f) COMPREPLY=( $( compgen -f $cur ) ) return 0 ;; +([^Izjy])f) ext='tar' regex=$ext ;; *z*f) ext='tar.gz' regex='t\(ar\.\)\(gz\|Z\)' ;; *[Ijy]*f) ext='t?(ar.)bz?(2)' regex='t\(ar\.\)bz2\?' ;; *) COMPREPLY=( $( compgen -f $cur ) ) return 0 ;; esac if [[ "$COMP_LINE" == tar*.$ext' '* ]]; then #تکمیل فایلها روی فایل tar. # #کسب نام فایل tar از خط فرمان. tar=$( echo "$COMP_LINE" | \ sed -e 's|^.* \([^ ]*'$regex'\) .*$|\1|' ) #تعبیه چگونگی untar و لیست آن. untar=t${COMP_WORDS[1]//[^Izjyf]/} COMPREPLY=( $( compgen -W "$( echo $( tar $untar $tar \ 2>/dev/null ) )" -- "$cur" ) ) return 0 else #تکمیل فایل روی فایلهای وابسته. COMPREPLY=( $( compgen -G $cur\*.$ext ) ) fi return 0 } complete -F _tar -o default tar _make() { local mdef makef makef_dir="." makef_inc gcmd cur prev i; COMPREPLY=(); cur=${COMP_WORDS[COMP_CWORD]}; prev=${COMP_WORDS[COMP_CWORD-1]}; case "$prev" in -*f) COMPREPLY=($(compgen -f $cur )); return 0 ;; esac; case "$cur" in -*) COMPREPLY=($(_get_longopts $1 $cur )); return 0 ;; esac; # # # # if [ -f ${makef_dir}/GNUmakefile ]; then makef=${makef_dir}/GNUmakefile elif [ -f ${makef_dir}/makefile ]; then makef=${makef_dir}/makefile elif [ -f ${makef_dir}/Makefile ]; then makef=${makef_dir}/Makefile else makef=${makef_dir}/*.mk #قرار داد محلی. fi #قبل از اینکه فایلهای مقصد را پویش کنیم، دیدن آنکه #+آیا یک نام Makefile با -f مشخص شده است. for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do if [[ ${COMP_WORDS[i]} == -f ]]; then #eval برای بسط ~ (مد) eval makef=${COMP_WORDS[i+1]} break fi done [ ! -f $makef ] && return 0 #رسیدگی به Makefileهای پیوست شده. makef_inc=$( grep -E '^-?include' $makef | sed -e "s,^.* ,"$makef_dir"/," ) for file in $makef_inc; do [ -f $file ] && makef="$makef $file" done #اگر دارای یک پاره کلمه برای تکمیل هستیم، محدود #+نمودن تکمیلها به انطباقهای آن کلمه. if [ -n "$cur" ]; then gcmd='grep "^$cur"' ; else gcmd=cat ; fi COMPREPLY=( $( awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \ {split($1,A,/ /);for(i in A)print A[i]}' \ $makef 2>/dev/null | eval $gcmd )) } complete -F _make -X '+($*|*.[cho])' make gmake pmake _killall() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} #به دست آوردن لیستی از پردازشها #+(ارزیابی نخست sed به پردازشهای #+تولید شده توجه میکند، ارزیابی دوم #+متوجه کسب نام اصلی پردازش است). COMPREPLY=( $( ps -u $USER -o comm | \ sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \ awk '{if ($0 ~ /^'$cur'/) print $0}' )) return 0 } complete -F _killall killall killps #متغیرهای محلی: # # #پایان:
و این هم یک پاره کد از فایل .bash_profile آموزنده Andrzej Szelachowski.
مثال M-2. فایل .bash_profile
#از فایل ~/.bash_profile تنظیم Andrzej Szelachowski: #توجه کنید که اگر یک متغیر بخواهد export بشود، ممکن است #+به طرز برخورد ویژهای نیاز داشته باشد. DARKGRAY='\e[1;30m' LIGHTRED='\e[1;31m' GREEN='\e[32m' YELLOW='\e[1;33m' LIGHTBLUE='\e[1;34m' NC='\e[m' PCT="\`if [[ \$EUID -eq 0 ]]; then T='$LIGHTRED' ; else T='$LIGHTBLUE'; fi; echo \$T \`" #برای اینکه جایگزینی فرمان به طور لفظی به یک متغیر تخصیص #+داده شود، از escapeها و نقلقولهای دوگانه استفاده کنید: #+ #در غیر اینصورت، مقدار متغیر PCT فقط یکبار، وقتی متغیر از #+فایل .bash_profile صادر و خوانده شود، تخصیص داده میشود #+و پس از آن حتی اگر ID کاربر عوض شود، تغییر نخواهد کرد. PS1="\n$GREEN[\w] \n$DARKGRAY($PCT\t$DARKGRAY)-($PCT\u$DARKGRAY)-($PCT\! $DARKGRAY)$YELLOW-> $NC" #متغیری را که مقدارش تغییر میکند Escape کنید: # #وگرنه مقدار متغیر EUID فقط یکبار تخصیص داده میشود، #+مانند بالا. #وقتی متغیری تخصیص داده میشود، باید به صورت escape شده احضار شود: #+ #وگرنه مقدار متغیر T از لحظه export و خوانده شدن متغیر PCT از فایل #+.bash_profile گرفته میشود. بنابراین، در این مثال تهی خواهد بود. #وقتی مقدار متغیر شامل یک سمیکالن باشد، باید نقلقولی قوی بشود، #به این صورت: T='$LIGHTRED' در غیر اینصورت، سمیکالن به عنوان یک #جداکننده فرمان تفسیر خواهد شد. #متغیرهای PCT و PS1 میتوانند در یک متغیر جدید PS1 ادغام بشوند: PS1="\`if [[ \$EUID -eq 0 ]]; then PCT='$LIGHTRED'; else PCT='$LIGHTBLUE'; fi; echo '\n$GREEN[\w] \n$DARKGRAY('\$PCT'\t$DARKGRAY)-\ ('\$PCT'\u$DARKGRAY)-('\$PCT'\!$DARKGRAY)$YELLOW-> $NC'\`" #شگرد آن استفاده از نقلقولهای قوی برای بخشهای متغیر قدیمی PS1 است