我知道有些人有一些启动脚本,有些人则对提示进行个性化设置。一名开发人员将短别名用于他经常访问的长途路径和他经常运行的命令。
您在UNIX概要文件上进行了哪些有效的自定义操作,以提高生产率和易用性?
我知道有些人有一些启动脚本,有些人则对提示进行个性化设置。一名开发人员将短别名用于他经常访问的长途路径和他经常运行的命令。
您在UNIX概要文件上进行了哪些有效的自定义操作,以提高生产率和易用性?
Answers:
w!!
以下内容以root用户权限保存文件:
cmap w!! w !sudo tee % > /dev/null
grep
ing
时,请勿打扰设备或二进制文件:
alias grep='grep --color=auto --binary-files=without-match --devices=skip'
cat 1337.sh | webshare
alias webshare='curl -F "sprunge=<-" http://sprunge.us | xclip'
它会在您的剪贴板中返回一个简短的网址;您可以将其附加?whatever-lang
到返回的URL上,以突出显示其语法并为行编号。
set editing-mode vi
set keymap vi
在一个命令中创建目录和cd
大多数时候mkdir
,我的下一个命令是cd <that dir>
。
这样可以节省一些输入:
# make a directory and cd to it
mcd()
{
test -d "$1" || mkdir "$1" && cd "$1"
}
例如:
/home/mikel$ mcd somedir
/home/mikel/somedir$
我发现有用的另一件事是制作一次性目录的简便方法。例如,如果我正在编译程序,或者即使我正在尝试在此站点上重现问题。有时我可能会忘记清理目录。
# make a temporary directory and cd to it
mtd()
{
local dir
dir=$(mktemp -d)
if test -n "$dir"
then
if test -d "$dir"
then
echo "$dir"
cd "$dir"
else
echo "mktemp directory $dir does not exist"
fi
else
echo "mktemp didn't work"
fi
}
显示它的工作原理:
/home/mikel$ mtd
/tmp/tmp.wsnZjJ2KN6
/tmp/tmp.wsnZjJ2KN6$
我依靠的/tmp
是重新启动后清理系统,但是可以增强此功能,例如,使其退出外壳后删除temp dir。
mcd
了多年的版本,mtd
不久将添加一些内容。
mtd() { mcd $TMP/`date +%y%m%d-%H%M%S-%N`; }
。它可能缺乏便携性,但是对我来说已经足够了。
我想让bash提示符显示前一个命令的退出代码(如果它不为零)。我也喜欢我的外壳在使用时为我加油,所以我增加了一些傻气:
smiley() {
RC=$?
[[ ${RC} == 0 ]] && echo ':)' || echo ":( ${RC}"
}
export PS1="\$(smiley) \h [\A] [\W] \$ "
因此,当我运行命令时,会得到一些不错的视觉反馈:
:) mycomputer [23:03] [~] $ sh -c 'exit 0'
:) mycomputer [23:03] [~] $ sh -c 'exit 11'
:( 11 mycomputer [23:03] [~] $
编辑:这是我放在〜/ .bashrc中的东西
.bashrc
大概在。
.zshrc
:
alias l='ls -CF'
alias ll='ls -ClhF'
alias la='ls -CaF'
alias lla='ls -CalhF'
alias l.='ls -CAF --ignore=\*'
alias ll.='ls -CAlhF --ignore=\*'
alias t='tree -C'
PS1=$'%{\e[0;33m%}%m %{\e[32;1m%}%~ %{\e[0;31m%}%#%{\e[m%} '
bindkey '^[[3~' delete-char
export GREP_OPTIONS="--color"
.xmodmaprc
:
clear lock
keycode 9 = Caps_Lock ISO_Next_Group Caps_Lock ISO_Next_Group
keycode 66 = Escape NoSymbol Escape
add lock = Caps_Lock
(交换Escape键和Caps Lock键)。
因为我经常使用终端,所以我搞砸了bashrc(这使我可以快速学习并学习一些有趣的东西以及有趣的工具)。我通常在bashrc中定义许多功能。例子:
提取档案:
extract () {
libextract () {
if [ -f "$1" ] ; then
case "$1" in
*.tar.bz2) tar xjf "$1" ;;
*.tar.gz) tar xzf "$1" ;;
*.bz2) bunzip2 "$1" ;;
*.rar) rar x "$1" ;;
*.gz) gunzip "$1" ;;
*.tar) tar xf "$1" ;;
*.tbz2) tar xjf "$1" ;;
*.tgz) tar xzf "$1" ;;
*.zip) unzip "$1" ;;
*.Z) uncompress "$1" ;;
*.7z) 7z x "$1" ;;
*) echo "$1 ne moze biti raspakovan!" ;;
esac
else
echo "$1 nije validan fajl"
fi
}
echo "Unesite putanju do direktorijuma u kome se nalaze arhive: " && read dir && dirprovera && cd $dir
for f in *
do
mkdir ./$f-raspakovano && cd ./$f-raspakovano
libextract ./../$f
cd ./../
done
tipka
}
重命名文件和文件夹:
frename () {
if [ $# -gt 0 ]
then
dir="$(echo $1)"
dirprovera
cd $dir
for f in *
do
mv "$f" "`echo "$f" | tr -s " " "_" | tr "A-Z" "a-z"`" 2>/dev/null &
done
tipka
else
echo "Upotreba: frename [direktorijum]" >&2
fi
}
像这样将大文件分割成几个小文件:
fsplit () {
if [ $# -gt 1 ]
then
file="$(echo $1)"
SIZE="$(echo $2)"
PREFIX="$(echo $3)"
if [ -z "$PREFIX" ]; then PREFIX="fsplit"; fi
fileprovera
split -d -a 3 -b $SIZE $file "$PREFIX-part-" || echo "Doslo je do greske!"
tipka
else
echo "Upotreba: fsplit [fajl] [velicina] [prefix]
Za velicinu se koriste m (MB), g (GB) ili k (KB) (15m, 650kb, 4.7g...)
Prefiks moze sadrzati brojeve, slova, i crtice (primer: moj_pre-fiks)
Ukoliko ne unesete prefiks isti ce biti dodeljen automatski u sledecem formatu:
fsplit-part-XXX
gde XXX predstavlja broj dela fajla (001, 005, 189...)" >&2
fi
}
我还编辑了很多别名,因为我发现在某些情况下(例如在ls,grep和small命令中)使用带有默认参数的命令要容易得多,然后每次键入所有这些都容易得多。
(社区Wiki,因此每个技巧都属于一个单独的答案。)
安全登出
Ctrl+ D是退出Shell的最简单方法,但是如果仍然有作业在运行,无论如何它都会很高兴地退出Shell。默认情况下,这意味着您从该Shell内部运行的所有程序都将被杀死。
某些shell仅在按Ctrl+ D两次后才让您注销,但是意外地这样做仍然太容易了。
因此,请将其添加到.bashrc
或.zshrc
或您喜欢的任何配置文件中。
alias x='_exit'
# prevent running "exit" if the user is still running jobs in the background
# the user is expected to close the jobs or disown them
_exit()
{
case $- in *m*)
# this way works in bash and zsh
jobs | wc -l | grep -q '^ *0 *$'
if test $? -eq 0
then
command exit "$@"
else
jobs
fi
;;
*)
command exit "$@"
;;
esac
}
(社区Wiki,因此每个技巧都属于一个单独的答案。)
搜索历史记录以查找运行命令的所有方式
您可能已经知道Ctrl+ R,但是恕我直言,这种方法更加流畅。
设置Alt+ P以在历史记录中搜索以您已经键入的内容开头的命令。
例如ls
Alt+ P,Alt+ P,Alt+ P 将通过所有ls
命令向后搜索。
您需要将其放入/etc/inputrc
或.inputrc
中bash
:
$if mode=emacs
"\ep": history-search-backward
"\en": history-search-forward
$endif
这对于您.zshrc
来说zsh
:
bindkey -M emacs '^[p' history-beginning-search-backward
bindkey -M emacs '^[n' history-beginning-search-forward
您甚至可以更进一步,使“向上”箭头执行此操作。
简单的计算器
您可以使用$(( ... ))
或expr ...
进行非常基本的计算,但是可以进行整数除法,例如
$ expr 3 / 2
1
$ expr 1.5 \* 2
expr: non-integer argument
更好的方法是使用bc
。
# do some floating point arithmetic
calc()
{
echo "scale=3; $*" | bc
}
然后:
$ calc 3 / 2
1.500
$ calc 1.5 \* 2
3.0
alias py='PYTHONSTARTUP=~/.pythonstartup python'
包含我的计算器from math import *;
。整数除法问题仍未解决,但是它对于更复杂的操作更有用。
更好的制表符完成
我认为还没有人提到自定义Tab完成。
这就是我所拥有的。
它做的两个主要事情是:
cd <Tab>
仅建议目录d<Tab>
仍将完成Desktop
,Downloads
对于bash:
# custom tab completions
if type complete >/dev/null 2>&1
then
if complete -o >/dev/null 2>&1
then
COMPDEF="-o complete"
else
COMPDEF="-o default"
fi
complete -a alias unalias
complete -d cd pushd popd pd po
complete $COMPDEF -g chgrp 2>/dev/null
complete $COMPDEF -u chown
complete -j fg
complete -j kill
complete $COMPDEF -c command
complete $COMPDEF -c exec
complete $COMPDEF -c man
complete -e printenv
complete -G "*.java" javac
complete -F complete_runner -o nospace -o default nohup 2>/dev/null
complete -F complete_runner -o nospace -o default sudo 2>/dev/null
complete -F complete_services service
# completion function for commands such as sudo that take a
# command as the first argument but should complete the second
# argument as if it was the first
complete_runner()
{
# completing the command name
# $1 = sudo
# $3 = sudo
# $2 = partial command (or complete command but no space was typed)
if test "$1" = "$3"
then
set -- `compgen -c "$2"`
# completing other arguments
else
# $1 = sudo
# $3 = command after sudo (i.e. second word)
# $2 = arguments to command
# use the custom completion as printed by complete -p,
# fall back to filename/bashdefault
local comps
comps=`complete -p "$3" 2>/dev/null`
# "complete -o default -c man" => "-o default -c"
# "" => "-o bashdefault -f"
comps=${comps#complete }
comps=${comps% *}
comps=${comps:--o bashdefault -f}
set -- `compgen $comps "$2"`
fi
COMPREPLY=("$@")
}
# completion function for Red Hat service command
complete_services()
{
OIFS="$IFS"
IFS='
'
local i=0
for file in $(find /etc/init.d/ -type f -name "$2*" -perm -u+rx)
do
file=${file##*/}
COMPREPLY[$i]=$file
i=$(($i + 1))
done
IFS="$OIFS"
}
fi
对于zsh:
# set command completions
compctl -a {,un}alias
compctl -b bindkey
compctl -c command
compctl -/ {c,push,pop}d
compctl -E {print,set,unset}env
#compctl -c exec
compctl -f -x "c[-1,exec]" -c -- exec
compctl -j fg
# no -g according to zshcompctl
#compctl -g {ch}grp
compctl -j kill
compctl -c man
compctl -c nohup
compctl -u {ch}own
compctl -o {set,unset}opt
compctl -f -x "c[-1,sudo]" -c -- sudo
compctl -c {whence,where,which}
compctl -M '' 'm:{a-zA-Z}={A-Za-z}'
# make file name completion case-insensitive
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'
安全压缩
压缩程序默认情况下会删除原始文件。我不喜欢
alias gzip='gzip --keep'
alias bzip2='bzip2 --keep'
alias xz='xz --keep'
alias lzma='lzma --keep'
多行提示
tag() {
TAG="${TAG} [$1]" exec zsh
}
reset_tags() {
TAG='' exec zsh
}
color='green'
if [ "${USER}" = 'root' ]; then
color='red'
fi
export PS1="${TAG} %B%F{yellow} *** %F{blue}%~\
%F{yellow}%(1j.[%j] .)%F{red}%(?..(%?%) )%F{${color}}%n@%m %F{blue}%# %f%b"
export RPS1='%B%F{blue}%D{%Y-%m-%d} %F{green}%D{%H:%M:%S}'
export PS2='%B%F{red}%n@%m%k %B%F{blue}%_> %b%f%k'
unset color
您可以显示带有环境变量的“标签”。例:
tag 'DONT SHTUDOWN!!'
reset_tags
该代码至少部分基于this。
历史记录设置
dont_log() {
HISTFILE="/dev/null" TAG="${TAG} %B%F{red}[LOGGING DISABLED]" zsh
}
if [ "${HISTFILE}" != '/dev/null' ]; then
# history
export HISTFILE="${HOME}/.zsh/history"
export HISTSIZE="4096"
export SAVEHIST="4096"
# Don't overwrite, append!
setopt APPEND_HISTORY
# Write after each command
# setopt INC_APPEND_HISTORY
# Killer: share history between multiple shells
setopt SHARE_HISTORY
# If I type cd and then cd again, only save the last one
setopt HIST_IGNORE_DUPS
# Even if there are commands inbetween commands that are the same, still only save the last one
setopt HIST_IGNORE_ALL_DUPS
# Pretty Obvious. Right?
setopt HIST_REDUCE_BLANKS
# If a line starts with a space, don't save it.
setopt HIST_IGNORE_SPACE
setopt HIST_NO_STORE
# When using a hist thing, make a newline show the change before executing it.
setopt HIST_VERIFY
# Save the time and how long a command ran
setopt EXTENDED_HISTORY
setopt HIST_SAVE_NO_DUPS
setopt HIST_EXPIRE_DUPS_FIRST
setopt HIST_FIND_NO_DUPS
fi
如果您可以打开自动完成和文件名拼写更正!这可能是两件事可以为您节省最多的时间。然后,学习使用它们-Bash和Zsh具有制表符补全功能。Ksh的转义反斜杠效率很低,因此我建议不要使用Ksh。
我用的是Zsh,但是这样的别名几乎可以在除Csh之外的所有shell中使用:
alias l='ls -FC --color=tty'
alias ls='ls -FC --color=tty'
alias h=history
alias m=more
alias vi=vim
alias cx='chmod +x'
似乎应该在其中加上“ ps”的别名,但是我发现自己以多种方式使用“ ps”,但到目前为止我还没有发现任何东西。
在Zsh中,设置您的RPROMPT(不是拼写错误!)变量:
RPROMPT='%d'
整个目录显示在命令行的右侧,可以进行剪切粘贴。以后再说。
您应该使用正确编译的现代Vim,因为它可以将多个vim窗口放入一个文件和多个缓冲区中。您的.vimrc可能包含以下内容:
set mouse=c
set ml
set mls=5
set nowrap
set nobackup
set nonu
set showmatch
set tabstop=4
set shiftwidth=4
set showmode
set showcmd
set ruler
set notextauto
set laststatus=2
set mps=(:),{:},[:],<:>
set modelines=0
其中很多是个人喜好,但我确实相信8空格制表符会使代码的可读性降低,并且有大量研究对此进行了证明。
同样,“ mouse = c”很重要。您不应该使用鼠标在文件内移动。将手从键盘上移开,触摸鼠标,然后将它们向后移,这很慢。使用“ hjkl”光标移动以及其他键盘分页和光标移动键。
如果您使用的是X11,则应对Xterm配置进行一些操作。这来自我的.Xresources文件:
XTerm*VT100.scrollBar: true
XTerm*VT100.saveLines: 1000
XTerm*VT100.cutNewLine: false
XTerm*VT100.cutToBeginningOfLine: false
XTerm*VT100.charClass: 33:48,35:48,37:48,42:48,45-47:48,64:48,95:48,126:48
XTerm*VT100*translations: #override \n\
<Key>F2: insert-selection(PRIMARY,CUT_BUFFER0)
默认情况下,给Xterm一个滚动条,在缓冲区中保存1000行文本,这很标准。
charClass指令使“单词”包含诸如“。”,“ /”和“ *”之类的内容。双击以“ /”分隔的文件名的任何部分,就可以得到整个内容,少了“:”字符。
cutToBeginningOfLine与上面的Zsh RPROMPT一起使用。三次单击出现在命令行RHS上的当前工作目录的路径,然后仅选择路径:复制停止在单词的开头。习惯了之后就会非常高效。
上面的X资源还使成为粘贴键。这样,复制(可能使用鼠标)后,您可以粘贴而无需将手移回鼠标单击。
Esc``Esc
或Esc``=
在ksh
,并Tab
在工作ksh93
。以防万一有人卡住或喜欢它。
添加最后一个命令的非零返回值是一个好主意。我认为原始海报专门询问了.profile / .cshrc / .bashrc。值得一提的是其他通常自定义的RC文件的列表,但是对于这个问题,我只会坚持使用shell自定义。
最近,我还在提示符下添加了一个标志,该标志在shell在屏幕下运行时显示。它使用solaris的“ ptree”命令搜索祖先进程,但是您可以在Linux上使用“ pstree”命令执行相同的操作。
SCREEN=""
if [ -f /usr/bin/ptree ]; then
if ptree $$ | grep -v grep | grep -w screen > /dev/null 2>&1; then
SCREEN="SCREEN "
fi
fi
我花了几分钟的时间弄清楚如何嵌入最后一条命令的返回代码,因此我将其张贴在这里。
PROMPT_COMMAND='if [ "$?" = 0 ]; \
then RC=""; \
else RC="RV=$? "; fi; PS1="% ${SCREEN}\h $RC\w\n% "'
我敢肯定,可以做得更漂亮。:-)
未来的技巧,请注意阅读$?在使用“ if [”之后。如果左括号是内置括号,它将不会覆盖$?的值。但是,如果您使用[不是内置的shell,那么它将重置$?的值?经过测试。分配$更安全?立即放入一个临时变量,然后测试该变量。
显示最近更改的文件
通常,我想查看最新的文件。例如,我可能在logs目录中,并想查看哪个文件是最新的,因为这是查看为什么某些文件不起作用的第一个地方。
ls -lt | head
输入起来很麻烦,所以这里有一个替代方法:
# show the most recently changed file
latest()
{
if test $# -ne 0
then
/bin/ls -t -1 -d "$@" | head -n 1
else
/bin/ls -t -1 -d * | head -n 1
fi
}
它还需要一个通配符或文件列表,例如
$ latest mail* syslog*
syslog
如果所有日志文件的名称都带有时间戳,这将特别方便。您可以找到该程序的最新日志,而不必担心时间戳的格式。
$ touch -d 'Feb 1' mylog.20110201
$ touch -d 'Feb 2' mylog.20110202
$ touch -d 'Feb 3' mylog.20110203
$ latest mylog*
mylog.20110203
这是扩展版本,支持-<number>
打印<number>
行而不是一行的选项。
# show the most recently changed file
latest()
{
local count=1 # how many files to print
local promptlines=5 # how many lines to leave for the prompt
# when printing a screenful with -s
local usage="Usage: latest [-n <number>] [-s] [--] [pattern]"
while test $# -gt 0
do
case $1 in
# -- = stop processing options
--)
shift
break
;;
# -n <number> = <number> files
-n)
if test -n "$2"
then
count=$2
shift 2
else
echo "$usage" 1>&2
return 1
fi
;;
# -s = one screenful
-s)
count=$((LINES - promptlines))
shift
;;
# -<number> = <number> files
-[0-9]*)
count=${1#-}
shift
;;
# anything else starting with a minus is a usage error
-*)
echo "$usage" 1>&2
return 1
;;
*)
break
;;
esac
done
if test $# -ne 0
then
/bin/ls -t -1 -d "$@" | head -n $count
else
/bin/ls -t -1 -d * | head -n $count
fi
}