php中的curl几点需要注意的地方

On 十二月 2, 2012, in 技术记录, by pensz

1 CURLOPT_POSTFIELDS中的玄机

curl_setop($ch, CURLOPT_POSTFIELDS, $var); 但不知道内有玄机,php的doc里面有这么一段话。

If value is an array, the Content-Type header will be set to multipart/form-data.

要知道一般POST时,会以application/x-www-form-urlencoded 的 Content-Type POST。而 multipart/form-data 一般用于上传文件。

关于两者的区别,不想读rfc的可以先看看 http://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data

两种情形下POST样例:

application/x-www-form-urlencoded 形式的POST

POST / HTTP/1.1
Host: 192.168.201.197
Accept: */*
Accept-Encoding: gzip
Content-Length: 8
Content-Type: application/x-www-form-urlencoded

url=xxxx

multipart/form-data 格式的POST:

POST / HTTP/1.1
Host: 192.168.201.197
Accept: */*
Accept-Encoding: gzip
Content-Length: 153
Content-Type: multipart/form-data; boundary=—————————-e62c3de4a033

Content-Disposition: form-data; name=”url”

xxx

2 curl中PUT文件

现在都流行RESTful的接口,很多接口要求客户端PUT方式上传文件。在php中,使用curl发起PUT的请求,有两种方法:

curl_setopt($ch, CURLOPT_PUT, 1);
或者
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, ‘PUT’);

当你想使用PUT上传文件时,请不要使用第二种,因为它不会上传文件。

 

Tagged with:  

关于bash的启动运行的文件

On 十二月 1, 2012, in 技术记录, by pensz

工作上经常碰到环境变量不对,bash运行行为和自己期望的不一致,于是想花点时间看看bash.

说起来,这件事情应该再简单不过了,看看bash手册上写的便是了.

http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

但是坦白来说,我花了很长时间才看明白了一点.

看到的一些结论
如果是login的shell,那么bash在运行先执行 /etc/profile ;然后依次查找 ~/.bash_profile, ~/.bash_login, ~/.profile;如果找到其中一个文件就执行之,后面的就不执行了.

如果是interactive的非login shell,则先会执行 /etc/bash.bashrc,如果~/.bashrc存在的话,接着执行~/.bashrc.

如果是非interactive的,且非login shell,则执行 $BASH_ENV 对应的shell.

ssh到远端的机器,远端机器上的bash会执行什么呢?如果是login shell,不用说,和第1种一样;如果是ssh remote-machine ‘cmd’这种的(也就是我们一般shell脚本里面调用形式),则会执行~/.bashrc(远端机器上的bash在编译bash的时候define了SSH_SOURCE_BASHRC ).

有些问题
什么是interactive shell,什么是login shell

interactive shell就是顾名思义,有用户交互的,检查方法就是在命令行下执行 echo $-,如果有i这个选项,则就是interactive shell 了.

login shell简单来说就是bash启动的时候加了 -l选项.

举几个实际的例子:

interactive & login shell:

linux登录到真实的终端tty1

interactive & non-login shell:

打开终端模拟器,在终端模拟器里面执行/bin/bash -i cmdfile

non-interactive & login shell

在终端模拟器里面执行/bin/bash -l cmdfile

non-interactive & non-login shell:

在终端模拟器里面执行/bin/bash cmdfile

为什么我在手动在机器上可以ssh到远端机器的,但是在shell脚本里面不行?

这种情形出现在ssh到远端机器的private key是有passphase 的,简单来说,ssh 到远端机器的时候,你还需要输入这个pass phase的,那为什么你一般ssh到远端机器的时候不要输入passphase呢,这个就是ssh-agent的功劳了,ssh通过环境变量中的SSH_AUTH_SOCK和SSH_AGENT_PID获得真实的private key。

简单来说,因为这个时候有了SSH相关环境变量。这些环境变量一般在通过keychain设置的,而keychain一般是startup脚本里面执行的。 解决办法就是bash -l.

骗人吧,按你的说法,ssh过去要执行~/.bashrc的,但是我~/.bashrc里面的命令没有执行

应该.bashrc里面有一段话,[ -z "$PS1" ] && return 也就是说,如果是非interactive的时候,PS1不会被设置,然后就return了,后面的命令当然没有执行.

interactive & login 的shell怎么也执行 ~/.bashrc 了?

看看 ~/.bash_profile, ~/.bash_login, ~/.profile 这几个文件中,应该有写

if [ -f "$HOME/.bashrc" ]; then
. “$HOME/.bashrc”
fi
ssh remote-machine ‘cmd’ 为什么不行啊?

一样的道理,PATH环境变量不是在 ~/.bashrc里面设置的.

ssh remote-mache ‘cmd’ 的时候不执行~/.bashrc啊?

编译bash的时候没有define SSH_SOURCE_BASHRC.

我的cmdfile在shebang部分里面已经声明了#!/bin/bash -l 了,但是它表现的不是login shell

不要使用 /bin/bash cmdfile 这种方式运行,要么使用cmdfile直接运行,要么使用/bin/bash -l cmdfile运行.

Tagged with: