好用的shell命令行: fish的配置
fish的可视化配置命令:
$ fish_config
另外,fish还有个叫 oh-my-fish 的外观美化插件,见: https://github.com/oh-my-fish/oh-my-fish
fish 很好的资源列表:
https://github.com/JorgeBucaran/awesome-fish
其配置文件夹为 ~/.config/fish。
1、要设置环境变量,在配置文件夹里新建 config.fish 文件,它会作为fish 启动时的加载文件,相当与bash的.bashrc,然后在里面配置环境变量,其环境变量配置方法与bash不同,格式如下:
# There are three kinds of variables in fish: universal, global and local variables. # Universal variables are shared between all fish sessions a user is running on one computer. # Global variables are specific to the current fish session, but are not associated with any # specific block scope, and will never be erased unless the user explicitly requests it using set -e. # Local variables are specific to the current fish session, and associated with a specific block of # commands, and is automatically erased when a specific block goes out of scope. # A block of commands is a series of commands that begins with one of the commands for, while , if, function, # begin or switch, and ends with the command end. # The user can specify that a variable should have either global or local scope using the -g/--global or -l/--local switches. # Variables can be explicitly set to be universal with the -U or --universal switch, # global with the -g or --global switch, or local with the -l or --local switch. set -x JAVA_HOME /home/hzh/hzh/soft/jdk set -x JRE_HOME {$JAVA_HOME}/jre
# 按照bash风格用:来分割多个值,但在fish中PATH不能用:来分割,必须用空格分割 set -x CLASSPATH .:{$JAVA_HOME}/lib:{$JRE_HOME}/lib set -x PATH {$JAVA_HOME}/bin {$PATH} set -x ANDROID_HOME /home/zhou/android/android_adt/sdk set -x PATH {$PATH} {$ANDROID_HOME}/build-tools/22.0.1 set -x PATH {$PATH} {$ANDROID_HOME}/platform-tools set -x PATH {$PATH} {$ANDROID_HOME}/tools set -x NDK_HOME /home/zhou/android/android_adt/ndk set -x PATH {$PATH} {$NDK_HOME} set -x PATH {$PATH} /home/zhou/android/android_adt/eclipse set -x GRADLE_HOME /home/hzh/hzh/soft/gradle set -x PATH {$PATH} {$GRADLE_HOME}/bin
# 设置局部变量,必须用空格分割name及value,不能象bash那样用=来赋值 set -l MAVEN_HOME '/home/hzh/hzh/soft/maven' set -x PATH {$PATH} {$MAVEN_HOME}/bin set -x CATALINA_HOME /home/hzh/hzh/soft/tomcat
另外,对于那些必须要用引号 : 隔开的环境变量(如ld.so需要的环境变量 LD_LIBRARY_PATH),则:
-
The problem now is that there are many other environment variables which need to be colon-delimited, but Fish does not do that. For example, the dynamic linker
ld.so
that is used to load up DLLs when a binary executes requiresLD_LIBRARY_PATH
environment variable to be colon-delimited. I got errors when this variable was set using space-delimiters: cannot open shared object file: No such file or directory -
If you run into any problems with an environment variable that takes a series of values, then check back to see how it is set in traditional shells like Bash. If it is colon-delimited there, then you might need to make it colon-delimited in Fish too. But, do remember to enclose it in double quotes for variable expansion to work correctly. For example:
set -x FOO_ENV_VAR "/home/joe/bin/some_foo_dir:$FOO_ENV_VAR"
2、若要定义alias,但fish里没有alias这个说法,因此官方介绍用function来替代alias。具体是这样的,在配置文件夹里( ~/.config/fish/ )新建一个名为functions的文件夹(建完之后 ~/.config/fish/functions),此文件夹里存放你所定义的function,function名就是文件名,后缀为.fish, 在fish启动的时候,所有位于functions文件夹里的以后缀.fish结尾的函数都会被自动加载,这样就定义了一个alias。如:
functions/meld.fish:
function meld --description 'compare files' /usr/bin/meld 1>/dev/null 2>&1 $argv end
每个函数都必须带参数 $argv,这是shell传过来的参数。
上面的说法有误,fish有alias的,放到 config.fish 里,但是它也等价于函数,无法这后台运行:
# 下面这句可以后台运行,因为 xdg-open 本身就是后台运行的程序
alias hopen 'xdg-open 2>/dev/null'
3、有别与bash的`键,fish里采用括号来完成命令执行的功能:
在bash中,使用 ls `which ls` 可以显示 /bin/ls。 而在fish中,使用 ls (which ls) 可以显示 /bin/ls。 用 echo a(data)则输出: a2016年 09月 23日 星期五 15:49:18 CST。
4、bash中的ctrl+r的搜索历史命令的功能(不断按ctrl+r可以继续搜索),在fish中已经得到了很好的解决,你只需要键入你想搜索的历史命令中的某写字母,再按ctrl+p就能不断搜索历史命令。
5、fish的function不能运行在后台,即加 & 没什么用。
6、fish的prompt, 在functions目录加入文件 fish_prompt.fish ,其内容为:
# 其中的 (hostname) (prompt_pwd) 为shell命令, $USER 为环境变量, __fish_prompt_hostname 为临时变量
function fish_prompt if not set -q __fish_prompt_hostname set -g __fish_prompt_hostname (hostname) end set_color -o cyan echo -n -s "$USER" @ "$__fish_prompt_hostname" ": " set_color -o green echo -n (prompt_pwd)
# 也可以用这个: echo -n ' $ ' echo -n " \$ " set_color normal end
这个prompt只是如果自己写prompt的一个演示,其实我们不用自己写prompt,fish自带的prompt就很好用。不过我们可以在prompt的前面加上当前时间,效果形如:01-16/15:26:04 hzh@hzh-bst ~/w/d/bring-up> 其中01-16表示日期。要加上这种日期,只需要在prompt里的echo里加入 (date "+%m-%d/%H:%M:%S")" " 即可。
7、去掉欢迎信息(greeting message)
欢迎信息是一个fish function,位于 /usr/share/fish/functions/fish_greeting.fish。
8、fish种的 \x1e 是什么,其实就一个分隔符,它的定义为:
/** Character for separating two array elements. We use 30, i.e. the ascii record separator since that seems logical. */ #define ARRAY_SEP 0x1e /** String containing the character for separating two array elements */ #define ARRAY_SEP_STR L"\x1e"
测试结果:
# 数组 [a] [b]
$ set aaa (printf 'a\x1eb') $ count $aaa 2
# 数组 [a\x1fb]
$ set aaa (printf 'a\x1fb') $ count $aaa 1
很明显,它是一个数组的分隔符.
9、fish 的颜色配置,主要都在 .config/fish/fish_variables 文件里。你不用直接改这个文件,可以使用 set 函数来间接修改这个文件。几个常用的颜色为:fish_color_user(prompt的登录用户颜色),fish_color_host(prompt的host颜色),fish_color_cwd(prompt的目录路径颜色)。直接在命令行设置如:set fish_color_user 00ff00。
ubuntu下fish shell设置 256 color:
首先运行:
- tput colors -This will report how many colors your terminal is using.
- echo $TERM -This will tell you what terminal you are using.
- echo $COLORTERM -If you are using a gnome you should see gnome-terminal.
确保使用的是 xterm。
在终端点击菜单 编辑-》配置文件首选项, 再点“命令”tab, 然后勾选上“运行自定义命令而不是shell”,在里面敲入: env TERM=xterm-256color /usr/bin/fish
10, fish 的插件,命令行增强,特别是历史命令模糊搜索(fuzzy search),太好用了:
https://github.com/PatrickF1/fzf.fish,如果这个不能访问了,我自己有个fork:https://github.com/welhzh/fzf.fish。
功能包括:1,tab补全命令的时候可以模糊匹配补全;2,可以随时按 ctrl+alt+f 搜索目录文件(f for file);3,ctrl+r搜索历史命令;4,git的时候可以直接 ctrl+alt+l 搜索log的hash(l for log)。
fish shell 的命令行语法:
Fish 的语法非常自然,一眼就能看懂。
if
语句:
if grep fish /etc/shells echo Found fish else if grep bash /etc/shells echo Found bash else echo Got nothing end
switch
语句:
switch (uname) case Linux echo Hi Tux! case Darwin echo Hi Hexley! case FreeBSD NetBSD DragonFly echo Hi Beastie! case '*' echo Hi, stranger! end
while
循环:
while true echo "Loop forever" end
for
循环:
for file in *.txt cp $file $file.bak end
fish 的函数
Fish 的函数用来封装命令,或者为现有的命令起别名,可在配置文件夹里定义函数文件(文件名必须是函数名),或者在命令行直接定义函数:
function llss ls -lhG $argv end
上面代码定义了一个llss
函数。命令行执行这个函数以后,就可以用llss
命令替代ls -lhG
。其中,变量$argv
表示函数的参数,每个定义的函数都必须带这个参数,由fish负责参数值的传递。
下面是另一个例子:
function ls command ls -hG $argv end
上面的代码重新定义ls
命令。注意,函数体内的ls
之前,要加上command
,否则会因为无限循环而报错。
下面是我自己写的一个较完整的fish函数示例:
function testecho echo $argv[1] # $status 使用一次就会被清空,所有暂存它 set result $status if [ 0 -eq $result ] echo command execute success else echo $result echo command execute failed return end
# 下面的命令执行结果不为0,即执行不成功 SOME_ERROR_COMMAND set result $status if [ 0 -eq $result ] echo command execute success else echo $result echo command execute failed return end sleep 1 echo $argv[2] end
fish 中对argv参数进行interate:
function sss for a in $argv set aa (math "$a+1") myecho $a $aa end echo "" for a in $argv[1..-1] myecho $a $a+1 end end
其中 myecho 为:
function myecho echo $argv[1] $argv[2] end
对于单引号和双引号的使用请参照如下示例:
$ A=B\ C $ echo '"$A"' # 最外面的是单引号, 输出结果: "$A" $ echo "'$A'" # 最外面的是双引号, 输出结果: 'B C'
function vote_eosnameswaps --description 'vote each account of eosnameswaps' echo "begin ..." echo "" set CLEOS /home/hzh/github/eos_build/programs/cleos/cleos for each_voter in $argv[1..-1] echo $each_voter ./cleos -v -u http://api.eosnewyork.io push action eosnameswaps vote '[ "p.eos","'$each_voter'" ]' -p $each_voter@active sleep 1 end echo "" echo "finished" end
fish shell 读取文本文件然后将头尾的空字符去掉,替换中间所有2个及2个以上的连续空字符为一个空格,然后在分割成可以单独使用的元素:
function read-file-trim-split for line in (cat /tmp/hzh) set all "$all $line" end set all (string trim $all) set all (string replace -ar "\\s{2,}" " " $all) set all (string split " " $all) echo $all for word in $all echo $word end end
fish shell 中的比较和数学运算:
function go set d 66 while true set d (math "$d * 1.1 + 0.003") if math "$d > 117" break end echo $d end end
fish 中的字符串比较,参数iterate, switch等:
function rm --description 'vote each account of eosnameswaps' if test (count $argv) -lt 1 return 0 end # for a in $argv[1..-1] # if test $a = "." # echo "no" # return 1 # end # end for i in (seq (count $argv)) if test $argv[$i] = "." echo "do not delete ./" return 1 end if test $argv[$i] = "./" echo "do not delete ./" return 1 end switch $argv[$i] case "*..*" echo "do not delete ../ or ../../ or ../file etc." return 1 case "-*" set argv[$i] "" end end # if test (count $argv) -lt 2 -o "$argv[1]" = "--help" # echo "" # end echo "move it/them to trash." gio trash $argv end
支付宝扫一扫捐赠
微信公众号: 共鸣圈
欢迎讨论,邮件: 924948$qq.com 请把$改成@
QQ群:263132197
QQ: 924948