1. 提示符中显示用户名,主机名和当前工作目录

这个例子中PS1将在提示符中显示以下三种信息

  • \u – 用户名
  • \h – 主机名
  • \w – 当前工作目录的绝对路径
1
-bash-3.2$ export PS1="\u@\h \w> "
1
ramesh@dev-db ~> cd /etc/mail
1
ramesh@dev-db /etc/mail>

2. 提示符中显示当前时间

在PS1环境变量中,你可以使用$(linux_command)这种格式直接执行任何linux指令,在下面的例子中,通过执行指令$(date)在提示符中显示当前时间

1
ramesh@dev-db ~> export PS1="\u@\h [\$(date +%k:%M:%S)]> "
1
ramesh@dev-db [11:09:56]>

你也可以使用\t以hh:mm:ss格式显示当前的时间

1
ramesh@dev-db ~> export PS1="\u@\h [\t]> "
1
ramesh@dev-db [12:42:55]>

你也可以像下面的示例一样使用\@ 以12小时am/pm格式显示当前时间

1
ramesh@dev-db ~> export PS1="[\@] \u@\h> "
1
[04:12 PM] ramesh@dev-db>

3. 在提示符中显示任一linux指令输出

你可以在提示符中显示任何linux指令的输出.下面的例子在提示符中显示三项用|(pipe)分割的信息

  • \!: 显示历史指令记录数
  • \h: 主机名
  • $kernel_version:  uname -r 指令的输出
  • \$?: 上一条指令的状态
1
ramesh@dev-db ~> kernel_version=$(uname -r)
1
ramesh@dev-db ~> export PS1="\!|\h|$kernel_version|\$?> "
1
473|dev-db|2.6.25-14.fc9.i686|0>

4. 更改提示符的前景色

Display prompt in blue color, along with username, host and current directory information

使用蓝色显示提示符,包括用户名,主机名和当前工作目录信息

$ export PS1="\e[0;34m\u@\h \w> \e[m" [Note: This is for light blue prompt]  $ export PS1="\e[1;34m\u@\h \w> \e[m" [Note: This is for dark blue prompt]
  • \e[ - 提示符颜色的开始处
  • x;ym - 颜色值., 使用下面提到的数值
  • \e[m - 提示符颜色的结束处

Color Code Table:

Black 0;30 Blue 0;34 Green 0;32 Cyan 0;36 Red 0;31 Purple 0;35 Brown 0;33 [Note: Replace 0 with 1 for dark color]

将下面指令添加到.bash_profile或者.bashrc中,使其永久生效

1
STARTCOLOR='\e[0;34m';
1
ENDCOLOR="\e[0m"
1
export PS1="$STARTCOLOR\u@\h \w> $ENDCOLOR"

5. 更改提示符背景色

Change the background color by specifying \e[{code}m in the PS1 prompt as shown below.

想下面的例子一样在PS1中指定\e[{code}m 的值以更改背景色

1
$ export PS1="\e[47m\u@\h \w> \e[m"
 [Note: This is for Light Gray background]

组合背景色和前景色

1
export PS1="\e[0;34m\e[47m\u@\h \w> \e[m"
 [Note: This is for Light Blue foreground and Light Gray background]

将下面的代码添加到.bash_profile或者.bashrc中使背景色和前景色永久生效.

STARTFGCOLOR='\e[0;34m'; STARTBGCOLOR="\e[47m" ENDCOLOR="\e[0m" export PS1="$STARTFGCOLOR$STARTBGCOLOR\u@\h \w> $ENDCOLOR"

从下面的背景色中选择最符合你口味儿的颜色.

  • \e[40m
  • \e[41m
  • \e[42m
  • \e[43m
  • \e[44m
  • \e[45m
  • \e[46m
  • \e[47m

6. 在提示符中显示混合色

你也可以在同一提示符中显示混合色,将下面的函数添加到.bash_profile中

function prompt {   local BLUE="\[\033[0;34m\]"   local DARK_BLUE="\[\033[1;34m\]"   local RED="\[\033[0;31m\]"   local DARK_RED="\[\033[1;31m\]"   local NO_COLOR="\[\033[0m\]"   case $TERM in     xterm*|rxvt*)       TITLEBAR='\[\033]0;\u@\h:\w\007\]'       ;;     *)       TITLEBAR=""       ;;   esac   PS1="\u@\h [\t]> "   PS1="${TITLEBAR}\   $BLUE\u@\h $RED[\t]>$NO_COLOR "   PS2='continue-> '   PS4='$0.$LINENO+ ' }

你可以重新登陆使修改生效,或者像下面一样source .bash_profile

$. ./.bash_profile $ prompt ramesh@dev-db [13:02:13]>

7. 用tput更改提示符颜色

你也可以像下面一样在PS1中使用tput更改颜色

$ export PS1="\[$(tput bold)$(tput setb 4)$(tput setaf 7)\]\u@\h:\w $ \[$(tput sgr0)\]"

tput Color Capabilities:

  • tput setab [1-7] - Set a background color using ANSI escape
  • tput setb [1-7] - Set a background color
  • tput setaf [1-7] - Set a foreground color using ANSI escape
  • tput setf [1-7] - Set a foreground color

tput Text Mode Capabilities:

  • tput bold - Set bold mode
  • tput dim - turn on half-bright mode
  • tput smul - begin underline mode
  • tput rmul - exit underline mode
  • tput rev - Turn on reverse mode
  • tput smso - Enter standout mode (bold on rxvt)
  • tput rmso - Exit standout mode
  • tput sgr0 - Turn off all attributes

Color Code for tput:

  • 0 - Black
  • 1 - Red
  • 2 - Green
  • 3 - Yellow
  • 4 - Blue
  • 5 - Magenta
  • 6 - Cyan
  • 7 - White

8. 使用下面的PS1变量可用代码制作个性化的提示符

使用下面的代码制作一个符合你自己口味儿和所需要功能的个性化提示符.
  • \a an ASCII bell character (07)
  • \d the date in "Weekday Month Date" format (e.g., "Tue May 26")
  • \D{format} - the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
  • \e an ASCII escape character (033)
  • \h the hostname up to the first part
  • \H the hostname
  • \j the number of jobs currently managed by the shell
  • \l the basename of the shell's terminal device name
  • \n newline
  • \r carriage return
  • \s the name of the shell, the basename of $0 (the portion following the final slash)
  • \t the current time in 24-hour HH:MM:SS format
  • \T the current time in 12-hour HH:MM:SS format
  • \@ the current time in 12-hour am/pm format
  • \A the current time in 24-hour HH:MM format
  • \u the username of the current user
  • \v the version of bash (e.g., 2.00)
  • \V the release of bash, version + patch level (e.g., 2.00.0)
  • \w the current working directory, with $HOME abbreviated with a tilde
  • \W the basename of the current working directory, with $HOME abbreviated with a tilde
  • \! the history number of this command
  • \# the command number of this command
  • \$ if the effective UID is 0, a #, otherwise a $
  • \nnn the character corresponding to the octal number nnn
  • \\ a backslash
  • \[ begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
  • \] end a sequence of non-printing character

9. 在PS1变量中使用bash shell函数

你也可以在PS1中像下面一样调用一个bash shell函数

ramesh@dev-db ~> function httpdcount { >  ps aux | grep httpd | grep -v grep | wc -l > }  ramesh@dev-db ~> export PS1="\u@\h [`httpdcount`]> " ramesh@dev-db [12]> [Note: This displays the total number of running httpd processes]

你可以将下面的代码添加到.bash_profile或者.bashrc中使其永久生效

function httpdcount {   ps aux | grep httpd | grep -v grep | wc -l } export PS1='\u@\h [`httpdcount`]> '

10. 在PS1变量中使用shell脚本

你也可以在PS1中调用一个shell脚本,在下面的例子中,~/bin/totalfilesize.sh这个脚本被PS1变量调用,以显示当前目录总的文件数,

1
ramesh@dev-db ~> cat ~/bin/totalfilesize.sh
1
for filesize in $(ls -l . | grep "^-" | awk '{print $5}')
1
do
1
let totalsize=$totalsize+$filesize
1
done
1
echo -n "$totalsize"
1
ramesh@dev-db ~> export PATH=$PATH:~/bin
1
ramesh@dev-db ~> export PS1="\u@\h [\$(totalfilesize.sh) bytes]> "
1
ramesh@dev-db [534 bytes]> cd /etc/mail
1
ramesh@dev-db [167997 bytes]>
11. IP地址示例

my_ip=$(/sbin/ip addr show dev eth1 | perl -ne '/inet ([\d.]+)/ && print $1')
export PROMPT_COMMAND='echo -ne "\033]0;$my_ip\007"'
export PS1="\[\e[1;36m\][\H]\[\e[31;1m\]\u\[\e[0m\]@\[\e[32;1m\]$my_ip\[\e[0m\]:\[\e[35;1m\]\w\[\e[0m\]\\$ "

android是如何 DNS解析

[不指定 2014/02/10 13:22 | by ipaddr ]

通过ubuntu等Linux系统都是通过resolve.conf文件进行域名解析的,通过man resolve.conf可以查看到:

The  resolver is a set of routines in the C library that provide access to the Internet Domain Name System (DNS).  The  resolver  configuration file  contains  information  that  is read by the resolver routines the first time they are invoked by a process.  The file is designed  to  be human readable and contains a list of keywords with values that provide various types of resolver information. If this file doesn't exist the only name server to be queried  will  be       on  the  local machine; the domain name is determined from the hostname and the domain search path is constructed from the domain name.

所以DNS解析是由C库函数进行解析的,在Android中bionic/libc/docs/overview.txt文件中我们也可以看到:

DNS resolver:
 Bionic uses a NetBSD-derived resolver library which has been modified in the following ways:
    - don't implement the name-server-switch feature (a.k.a. <nsswitch.h>)
    - read /system/etc/resolv.conf instead of /etc/resolv.conf
    - read the list of servers from system properties. the code looks for 'net.dns1', 'net.dns2', etc.. Each property should contain the IP address of a DNS server.
      these properties are set/modified by other parts of the Android system (e.g. the dhcpd daemon).
      the implementation also supports per-process DNS server list, using the properties 'net.dns1.<pid>', 'net.dns2.<pid>', etc... Where <pid> stands for the numerical ID of the current process.
    - when performing a query, use a properly randomized Query ID (instead of a incremented one), for increased security.
    - when performing a query, bind the local client socket to a random port for increased security.
    - get rid of *many* unfortunate thread-safety issues in the original code
 Bionic does *not* expose implementation details of its DNS resolver; the content of <arpa/nameser.h> is intentionally blank. The resolver implementation might change completely in the future.

所以android关注的是resolv.conf以及net.dns1等属性。

通过adb shell中通过getprop查看属性,确实有net.dns1、net.dns2以及wifi中的net.tiwlan0.dns1以及 net.tiwlan0.dns2,移动网络中的net.rmnet0.dns1以及net.rmnet0.dns2等属性。
(tomzhou注:经测试,系统主要使用net.dns1, net.dns2两个配置进行解析,wifi & 3g网络在启用时,都会调用相关脚本设置这两个属性,同时还会修改net.change, net.dnschange等属性)。

实际代码中调用关系如下:

gethostbyaddr
   _dns_gethtbyaddr


_dns_gethtbyaddr
   _dns_gethtbyaddr
   res_nquery

_dns_gethtbyaddr
   __res_get_state

__res_get_state
   _res_thread_get


_res_thread_get
   res_ninit

res_ninit
   __res_vinit()

英文链接: Linux: What are some time-saving tips that every Linux user should know?

  翻译: 伯乐在线 高磊

  有网友在问答网站Quora上提问:“有哪些省时小技巧,是每个Linux用户都应该知道的?” Joshua Levy 平常就在 Linux 平台工作,并且他积累了不少实用命令行技巧,他在回复中精选出一部分。对技术用户来说,这些技巧挺重要或实用,但知道的人并不多。下文略有点长,一般来说,用户也不需要对全部内容都了解,但为了达到省时方便的目的,Joshua Levy  仍不遗余力做了校对,以保证列出的每一条都值得一读,前提是你是一位Linux重度用户。

  为了获取文中提到的一个命令的更多信息,先试下“man <命令名称>”,在一些情况下,为了让这条命令可以正常执行,你必须安装相应的包,可以用aptitude 或者 yum。如果失败了,求助Google。

  基础篇

  • 学习基础的Bash。事实上,读整个的bash的帮助手册;很容易理解而且篇幅也不算长。其他一些可选的shell外观可能更漂亮,但是bash功能很强大而且总是能用(主要学习zsh或者tcsh在很多情况下你会收到限制)。
  • 学习vim,对于Linux下的随机编辑,几乎没有工具能出其右(即使你大部分的时间里都在使用Emacs或者Eclipse)。
  • 了解ssh,以及跳过每次登陆时密码验证的基础办法,通过ssh-agent,ssh-add等命令。
  • 熟悉bash下的工作管理: &,Ctrl-Z,Ctrl-C,jobs,fg,bg,kill, 等等。
  • 基础的文件管理:ls 以及 ls -l (特别的,学习”ls -l”中列出的每一列字段的含义),less,head,tail,tail -f,ln,ln -s (学习软链接和硬链接的区别),chown,chmod,du(快速了解磁盘总体占用情况),df,mount。
  • 基础的网络管理命令:ip 或者 ifconfig,dig。
  • 了解正则表达式,以及grep、egrep的不同命令选项,-0,-A,-B 都值得了解一下。
  • 学习使用apt-get 或者 yum(取决于你的发行包)来找到并安装你需要的包.

  日常使用篇

  • 使用bash时,用Ctrl-R来搜索命令的历史记录。
  • 使用bash时,用Ctrl-W来清除最后一个单词,使用Ctrl-U来清除整行。可以查看man readline来获取bash里面默认键的绑定设置。内容很多。比如Alt-.(注:点)遍历之前命令中使用过的参数,Alt-* 扩展了参数的匹配模式。
  • 回到上次的工作目录:cd -。
  • 如果你的命令敲到一半时改变了主意,可以用Alt-#来在命令前面增加一个#,使之成为一行注释(或者使用Ctrl-A回到命令开头,然后再键入#)。你可以之后再通过搜索历史记录回来。
  • 使用xargs(或者parallel)。它非常强大。注意你能控制每一行(-L)执行多少项,也能控制如何并发(- P)。如果你不太确定它会如你所愿的工作,先使用xargs。 再者,-l{} 很有用。例如:
    find . -name \*.py | xargs grep some_function
  • cat hosts | xargs -l{} ssh root@{} hostname
  • pstree -p 可以很方便的显示整个进程树。
  • 使用pgrep 和pkill 来通过名字来发现进程或者给进程发信号(-f选项会有用)。
  • 了解你能向进程发送的信号种类。比如,要挂起一个进程,使用kill -STOP [进程ID]。要了解整个列表,请参考man 7 signal。
  • 如果你想让一个后台进程一直运行,使用nohup or disown 。
  • 通过netstat -lntp 来检测哪些进程在监听。同样可以用lsof。
  • bash脚本中,使用set -x 来调试输出。使用set -e在有错误时终止时终止执行。要想严格输出错误,可以考虑使用set -o pipefail(虽然这个主题说起来有些复杂)。对于更复杂的脚本,也可以使用trap。
  • bash脚本中,子shell(通过写在括号里)是一种组织命令的方便的方法。一个很常见的例子是暂时移动到另外一个工作目录,例如:
    #在当前目录下做一些事情 (cd /一些/另外的/目录;执行别的操作) #继续在原来的目录下执行
  • 要注意bash中有很多种变量表达式。检查一个变量是否存在:${name:?错误信息}。例如:如果一个bash脚本需要一个单变量,只需要写input_file=${1:?usage: $0 inpute_file}。数值扩展:i=$({(i+1)%5})。序列:{1..10}。字符串的整理:${var%suffix} 和${var#prefix}。例如:
    if var==foo.pdf, then echo ${var%.pdf}.txt   #会打印"foo.txt"
  • 通过 <(其他指令),一条命令的输出可以被当作是一个文件的内容来对待。 例如,比较本地和远程的 /etc/hosts 文件,可以用diff /etc/hosts <(ssh [远程主机] cat /etc/hosts)。
  • 了解bash中的“here documents”,比如 cat <<EOF …
  • bash中,通过 其他指令 > 日志文件 2>&1  把标准输出以及标准错误重定向。常见的情况是,为了保证一条指令没有为标准输入留下一个打开的文件描述符,从而输出至你当前所在的终端,增加“</dev/null” 也是好的习惯。
  • 用man ascii可以得到一个完整的ASCII表,有对应的16进制和10进制的值。
  • 通过ssh连接远程终端时,使用screen或者dtach 来保持你的session,防止被打断。在ssh中,了解如何使用-L或者-D选项(有时也会用到-R)会很有用处,比如,如果通过从一个远程的服务器访问一个网页。
  • 优化你的SSH选项也可能管用。比如,下面的.ssh/config 内容在一些网络环境下可以防止连接掉线,当连接到新主机时不需要再次确认,跳转验证,并且还使用了压缩(对在一些低宽带的连接环境下使用scp时会有帮助)。
    TCPKeepAlive=yes
  • ServerAliveInterval=15
  • ServerAliveCountMax=6
  • StrictHostKeyChecking=no
  • Compression=yes
  • ForwardAgent=yes

  数据处理篇

  • 把HTML转成文本:lynx -dump 标准输入
  • 如果要处理XML,xmlstarlet会很棒。
  • 对于Amazon S3,s3cmd 很方便(虽然还不太成熟,可能会有一些不太好的特性)。
  • 了解sort 以及 uniq(包括uniq的 -u 以及 -d 选项)。
  • 了解cut,paste,join 来操作文本文件。许多人使用cut但却忘了还有join。
  • 当你要在文件之间做集合的加,减,以及差运算时,用sort/uniq是非常方便的。假如a和b是两个已经去重的文本文件,那么运算起来会很快,而且可以在任意大小的文件之间执行操作,甚至可以到GB字节大小。(sort不受内存限制,不过如果/tmp 在一个很小的root分区的话,你可能需要使用-T选项)
    cat a b | sort | uniq > c   # c is a union b
  • cat a b | sort | uniq -d > c   # c is a intersect b
  • cat a b b | sort | uniq -u > c   # c is set difference a - b
  • 了解本地化会影响到许多命令行的工作,包括排序的顺序和性能。多数的linux安装包会把LANG或者其他一些本地化的变量设置为类似美国英语的一个本地设置。这会让sort和其他一些命令运行起来慢很多。(注意即使你使用UTF-8编码的文本,你仍然可以放心的通过ASCII码的顺序来排序,这一点用处很多)为避免i18n拖慢日常的工作,使用传统的基于字节的排序顺序,使用export LC_ALL=C(实际上,考虑在你的.bashrc里加进去)。
  • 了解基本的AWK和sed命令来做简单的数据处理。例如:对一个文本文件的第三列的数字求和:awk ‘{x += $3} END {print x}’。 这大概比同等的python速度要快三倍并且代码长度也会简短3倍。
  • 就地替换一个字符串在所有文件里所有出现的地方。
    perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt
  • 使用shuf来随机打乱一个文件中的行或者选择一个随机的行。
  • 了解sort的各个选项。知道键值是如何工作的。特别是,当你要使用 -k1时,要格外注意:1只对第一个字段排序,-k1则意味着根据整个行排序。
  • 稳定排序(sort  -s)可能会有用。例如,先根据第二个字段排序,再根据第一个字段排序时,你可以使用sort -k1,1 | sort -s -k2,2
  • 如果你需要在bash里的命令行里写入一个tab键的字面值的话,按Ctrl+V, <tab> 或者$‘\t’ (后者更好,因为你可以复制、粘贴)。
  • 对于二进制文件,使用hd来进行简单的导出16进制表示或者用bvi进行二进制的编辑。
  • 对于二进制文件,strings(还有grep等等)可以让你发现文件的字节位(0101).要对文件转编,可以试下iconv,或者如果要使用更高级的用法,试试uconv,它可以支持一些高级的Unicode方面的事情。比如,这条命令可以将重音都小写,并且去掉(通过扩展并且丢掉):
    uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt
  • 要将文件切片,可以试试split(根据大小切分)或者csplit(根据模式切分)。

  系统调试篇

  • 对于web调试来说,curl和curl -l会有用,以及和wget相同的那部分功能。
  • 如果想了解磁盘/cpu/网络的状态,可以使用iostat,netstat,top(更好一些的话,用htop),以及(尤其是)dstat,对于想快速了解系统当前正在发生的事情,非常的方便。如果想了解内存当前的状态,可以使用free以及vmstat,还要了解各项输出的含义。特别值得一提的是,你要知道“cached”的数值是linux内核保留用来做文件缓存的空间的大小,所以真正可用的有效内存是“free”项的对应值。
  • java的系统调试则完全是另外一回事,但在Sun以及其他的JVM上有一个简单的技巧,就是你可以运行kill -3 <pid> ,得到一个完整的栈调用轨迹以及堆使用的总体情况(包括产生的垃圾回收细节,这里面包含有很多的信息),会被定向到标准错误或者日志。
  • 使用mtr作为更好的网络追踪,识别网络存在的问题。
  • 要查看一个磁盘是否是满的,ncdu要比一般用的“du -sk *”要快。
  • 要查看哪些socket或者进程在占用带宽,试试iftop或者netlogs。
  • ab 工具(随apache的安装包一起发布)对于检测网络服务器的性能很有帮助,对于更加复杂的压力测试,可以试下siege。对于更加严重的网络问题的调试,试试wireshark或者tshark。了解strace和ltrace。这在一个程序突然失败,挂掉,或者崩溃,而你却不知所措,或者是你想知道程序的整体性能的情况时,会很有帮助。可以注意下-c和-p选项。
  • 了解用ldd来检查共享库函数等的一些问题。
  • 了解如何用gdb连接到一个正在运行的程序,并且得到它的调用堆栈。
  • 使用/proc. 对于现场调试问题会很有帮忙。例如:/proc/cpuinfo, /proc/xxx/cwd, /proc/xxx/exe, /proc/xxx/fd/, /proc/xxx/smaps。
  • 当要调试过去一段时间内出现的问题时,sar 会有用,它可以显示过去一段时间内的CPU,内存,网络的统计信息。
  • 对于更深层次的系统性能优化,可以关注下stap(systemtap)或者perf。
  • 当出现了一些很诡异的问题时,可以试下dmesg(比如硬件或者驱动的问题)。

CURL的POST较慢的问题的处理

[不指定 2014/01/13 17:09 | by ipaddr ]

在使用curl做POST的时候, 当要POST的数据大于1024字节的时候, curl并不会直接就发起POST请求, 而是会分为俩步,

  1.  1. 发送一个请求, 包含一个Expect:100-continue, 询问Server使用愿意接受数据
  2.  2. 接收到Server返回的100-continue应答以后, 才把数据POST给Server

这是libcurl的行为.

具体的RFC相关描述: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3

于是,这样就有了一个问题, 并不是所有的Server都会正确应答100-continue, 比如lighttpd, 就会返回417 “Expectation Failed”, 则会造成逻辑出错,,

要解决的办法也挺容易,改为GET或是 :

  1. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
  2.               // Disable Expect: header (lighttpd does not support it)

一个Apache故障分析过程

[不指定 2013/08/17 21:04 | by ipaddr ]

故障现象为Apache进程数不断上涨,最终达到最大进程数后无法再提供服务,access.log日志也不再滚动,修改日志格式输出请求处理时间后,发现部分请求达到30,60,90s+,初步判断为部分请求处理时间超长,长时间占用apache进程,导致新请求后只能派生新进程,最终所有进程都被长请求占用后,无法再提供服务.

使用  strace -p $ApachePID  跟踪发现,Apache进程都卡在:

recvfrom(29,  <unfinished ...>

进入 /proc/PID/fd/,查找fd=29的为某个socket:

29 -> socket:[968385]

再从/proc/net/tcp中找到id=968385的socket:

grep "968385" /proc/net/tcp


将IP地址,端口转换为10进制后,找到了后端挂掉的服务IP和端口,重启服务后恢复正常.

https://github.com/bitly/nsq

Introduction

NSQ is a realtime distributed messaging platform designed to operate at bitly’s scale, handling billions of messages per day (current peak of 90k+ messages per second).

It promotes distributed and decentralized topologies without single points of failure, enabling fault tolerance and high availability coupled with a reliable message delivery guarantee. See features & guarantees.

Operationally, NSQ is easy to configure and deploy (all parameters are specified on the command line and compiled binaries have no runtime dependencies). For maximum flexibility, it is agnostic to data format (messages can be JSON, MsgPack, go-protobuf, or anything else). Official Go and Python libraries are available out of the box and, if you’re interested in building your own client, there’s a protocol spec (see client libraries).

[转]Go项目的目录结构

[不指定 2013/05/31 17:14 | by ipaddr ]

项目目录结构如何组织,一般语言都是没有规定。但Go语言这方面做了规定,这样可以保持一致性

1、一般的,一个Go项目在GOPATH下,会有如下三个目录:

1|--bin
2|--pkg
3|--src

其中,bin存放编译后的可执行文件;pkg存放编译后的包文件;src存放项目源文件。一般,bin和pkg目录可以不创建,go命令会自动创建(如 go install),只需要创建src目录即可。
对于pkg目录,曾经有人问:我把Go中的包放入pkg下面,怎么不行啊?他直接把Go包的源文件放入了pkg中。这显然是不对的。pkg中的文件是Go编译生成的,而不是手动放进去的。(一般文件后缀.a)
对于src目录,存放源文件,Go中源文件以包(package)的形式组织。通常,新建一个包就在src目录中新建一个文件夹。

2、举例说明

比如:我新建一个项目,test,开始的目录结构如下:

1test--|--src

为了编译方便,我在其中增加了一个install文件,目录结构:

1test/
2|-- install
3`-- src

其中install的内容如下:(linux下)

1#!/usr/bin/env bash
2 
3if [ ! -f install ]; then
4echo 'install must be run within its container folder' 1>&2
5exit 1
6fi
7 
8CURDIR=`pwd`
9OLDGOPATH="$GOPATH"
10export GOPATH="$CURDIR"
11 
12gofmt -w src
13 
14go install test
15 
16export GOPATH="$OLDGOPATH"
17 
18echo 'finished'

之所以加上这个install,是不用配置GOPATH(避免新增一个GO项目就要往GOPATH中增加一个路径)

接下来,增加一个包:config和一个main程序。目录结构如下:

1test
2|-- install
3`-- src
4    |-- config
5    |   `-- config.go
6    `-- test
7        `-- main.go

注意,config.go中的package名称必须最好和目录config一致,而文件名可以随便。main.go表示main包,文件名建议为main.go。(注:不一致时,生成的.a文件名和目录名一致,这样,在import 时,应该是目录名,而引用包时,需要包名。例如:目录为myconfig,包名为config,则生产的静态包文件是:myconfig.a,引用该包:import “myconfig”,使用包中成员:config.LoadConfig()

config.go和main.go的代码如下:
config.go代码

1package config
2 
3func LoadConfig() {
4 
5}

main.go代码

1package main
2 
3import (
4    "config"
5    "fmt"
6)
7 
8func main() {
9    config.LoadConfig()
10    fmt.Println("Hello, GO!")
11}

接下来,在项目根目录执行./install

这时候的目录结构为:

1test
2|-- bin
3|   `-- test
4|-- install
5|-- pkg
6|   `-- linux_amd64
7|       `-- config.a
8`-- src
9    |-- config
10    |   `-- config.go
11    `-- test
12        `-- main.go
13(linux_amd64表示我使用的操作系统和架构,你的可能不一样)

其中config.a是包config编译后生成的;bin/test是生成的二进制文件

这个时候可以执行:bin/test了。会输出:Hello, GO!

3、补充说明

1)包可以多层目录,比如:net/http包,表示源文件在src/net/http目录下面,不过源文件中的包名是最后一个目录的名字,如http
而在import包时,必须完整的路径,如:import “net/http”

2)有时候会见到local import(不建议使用),语法类似这样:
import “./config”
当代码中有这样的语句时,很多时候都会见到类似这样的错误:local import “./config” in non-local package

我所了解的这种导入方式的使用是:当写一个简单的测试脚本,想要使用go run命令时,可以使用这种导入方式。
比如上面的例子,把test/main.go移到src目录中,test目录删除,修改main.go中的import “config”为import “./config”,然后可以在src目录下执行:go run main.go

可见,local import不依赖于GOPATH

4、Windows下的install.bat

1@echo off
2 
3setlocal
4 
5if exist install.bat goto ok
6echo install.bat must be run from its folder
7goto end
8 
9: ok
10 
11set OLDGOPATH=%GOPATH%
12set GOPATH=%~dp0
13 
14gofmt -w src
15 
16go install test
17 
18:end
19echo finished

注,冒号和ok之间不应该有空格,但是放在一起总是会被wordpress转成一个表情。汗……

5、更新日志

1)2012-12-05 发布
2)2013-04-13 修正:目录名可以和包名不同,但建议一致;将make文件名改为install

如果你在访问https网站时用 GoAgent 遇到证书无效问题,请按以下方法解决:

这里以Chrome浏览器为例,理论上只要证书正确导入系统,就可以了。

Ubuntu 系统:

打开 Chrome 浏览器
首选项 > 高级选项 > 管理证书…
在 授权中心 导入 GoAgent/local 目录下的 CA.crt 证书
(注意不要导入到 服务器 ,否则不起作用)
在 授权中心 找到 GoAgent CA 并点击 修改…
修改信任设置为全部选中
重启浏览器

Eclipse 在Ubuntu 下总是感觉上面的工具栏感觉特别的大,控件之间的空隙非常的大,和在Windows 下的感觉非常的不一样(毕竟是刚刚从windows叛逃出来),其实也不光光是Eclipse 是这样,其他也软件也同样有这个问题。尝试过通过更换主题来解决这样的问题,老是看着一个主题,审美总是会疲劳的。在网上找来一圈,

解决方案:

修改或者新建(系统默认是没有的)

  /home/Your_username/.gtkrc-2.0 (ubuntu中 . 开头的文件默认是隐藏文件,快捷键Ctrl+H可显示隐藏文件)

复制如下的内容:

style "gtkcompact" {
font_name="Sans 9"
GtkButton::default_border={0,0,0,0}
GtkButton::default_outside_border={0,0,0,0}
GtkButtonBox::child_min_width=0
GtkButtonBox::child_min_heigth=0
GtkButtonBox::child_internal_pad_x=0
GtkButtonBox::child_internal_pad_y=0
GtkMenu::vertical-padding=1
GtkMenuBar::internal_padding=0
GtkMenuItem::horizontal_padding=4
GtkToolbar::internal-padding=0
GtkToolbar::space-size=0
GtkOptionMenu::indicator_size=0
GtkOptionMenu::indicator_spacing=0
GtkPaned::handle_size=4
GtkRange::trough_border=0
GtkRange::stepper_spacing=0
GtkScale::value_spacing=0
GtkScrolledWindow::scrollbar_spacing=0
GtkExpander::expander_size=10
GtkExpander::expander_spacing=0
GtkTreeView::vertical-separator=0
GtkTreeView::horizontal-separator=0
GtkTreeView::expander-size=8
GtkTreeView::fixed-height-mode=TRUE
GtkWidget::focus_padding=0
}
class "GtkWidget" style "gtkcompact"
style "gtkcompactextra" {
xthickness=1
ythickness=1
}
class "GtkButton" style "gtkcompactextra"
class "GtkToolbar" style "gtkcompactextra"
class "GtkPaned" style "gtkcompactextra"

注销系统再次登录,打开Eclipse 的界面果然是紧凑来,感觉不错,打开其他的程序界面也同样是紧凑来不少。

界面美观了不少,但是Eclipse的自动提示的背景色是黑色的,看起来也非常的难受:

修改方案:

打开终端移动到当前主题目录下:

cd/usr/share/themes/当前的主题名/

打开gtk-2.0/gtkrc文件:

sudo gedit gtk-2.0/gtkrc 

寻找到“ntooltip_fg_color”和“ntooltip_bg_color”兩個屬性的值,如果沒有改屬性,可以自行添加,其值仿照windows的默認值,分別設定位:

tooltip_fg_color:#000000 tooltip_bg_color:#f2edbc

然後保存退出,打開系統外觀配置,切換一下主題,當切換回來的時候,修改的效果就生效了。

Clover 是 Windows Explorer 资源管理器的一个扩展,为其增加类似谷歌 Chrome 浏览器的多标签页功能。

方便的 Tab 页功能

要掌握功能强大,操作简单的标签页,只需记住Ctrl+T新开页面,Ctrl+W关闭页面,Ctrl+Tab切换页面,工作效率提高何止一倍!

操作系统无缝集成

Clover 通过 BHO 插件的形式,集成到 Windows Explorer,保留您通常的使用习惯,无需学习新的软件操作,马上就可以使用啦。

快如闪电的书签栏

按Ctrl+D添加当前路径,或者直接将文件夹拖入书签栏。再也不用到处寻找要访问的文件夹了,瞬间到达,何等痛快!

分页: 4/57 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]