2017年1月25日 星期三

linux 資料流重導向 (redirecte) stderr stdout


ref.鳥哥
ref.http://dywang.csie.cyut.edu.tw/dywang/linuxProgram/node20.html


資料流重導向

標準輸入(stdin) :代碼為 0 ,使用 < 或 << ;
標準輸出(stdout):代碼為 1 ,使用 > 或 >> ;
標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ;

>> 為 append
>   為覆寫


1> :是將正確的資料輸出到指定的地方去
2> :是將錯誤的資料輸出到指定的地方去
若只下> 則預設等義>1


將資料輸出到不同的地方去呢?可以這麼寫:
find /home -name testing > list_right 2> list_error


將錯誤的資訊丟掉!
 find /home -name testing > list_right 2> /dev/null


 find /home -name testing > list 2> list <==錯誤寫法

find /home -name testing > list 2>&1 <==正確寫法
or
find /var -name run &>file
請特別留意這一點呢!同時寫入同一個檔案需要使用 2>&1 才對呦!
(這邊我的理解為 把 stderr導向stdout 的address   2>&1) 如此一來 stderr 就變為stdout了


方便的make linux
 alias mkl='make linux vmimg 2>&1 | grep -i "error:\|correct"'




連續命令

指令間以分號( ; )隔開:連續執行指令。
[root@linux ~]# sync; sync; shutdown -h now

指令間以 && 隔開:前面指令執行結果正確,就接著執行後續的指令,否則就略過。
[root@linux ~]# ls /tmp && touch /tmp/testingagin
 ## 目錄/tmp存在,所以/tmp/testingagin會被建立。

[root@linux ~]# ls /csie && touch /csie/test
## 目錄/csie不存在,所以touch /csie/test不會被執行。

指令間以 || 隔開:前一個指令有錯誤時,後面的指令才被執行。
[root@linux ~]# ls /tmp/csieing || touch /tmp/csieing


2016年5月29日 星期日

linux 加入PATH 環境變數

http://linux.vbird.org/linux_basic/0320bash.php#settings

http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html


fast.

修改 ~/.bashrc 或 ~/.profile
  1. 若該變數為擴增變數內容時,則可用 "$變數名稱" 或 ${變數} 累加內容,如下所示:
    『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』
  2. 若該變數需要在其他子程序執行,則需要以 export 來使變數變成環境變數
    『export PATH』

ex.

vim ~/.bashrc
or
vim ~/.profile

加入以下

# User specific environment and startup programs
PATH=${PATH}:/opt/bin
export PATH


2016年5月26日 星期四

NAS learn



開啟ssh PubkeyAuthentication 服務
ref.https://www.chainsawonatireswing.com/2012/01/15/ssh-into-your-synology-diskstation-with-ssh-keys//?from=@


To start the process, you need to edit the SSH daemon’s config file to allow access via keys.

Edit/etc/ssh/sshd_config using vim & change these lines:

#RSAAuthentication yes 
#PubkeyAuthentication yes 
#AuthorizedKeysFile .ssh/authorized_keys

To this:

RSAAuthentication yes 
PubkeyAuthentication yes 
AuthorizedKeysFile .ssh/authorized_keys


Now get your permissions set correctly on that directory & file:> chmod 700 .ssh

> chmod 600 .ssh/authorized_keys

> chmod 700 .ssh/

再來是client 端 ,基本的概念就是使用private key 去開在遠端server public key

生成privatekey 和publickey
#ssh-keygen 

copy 到遠端的~/.ssh下
#scp id_rsa.pub username@serverip:~/.ssh/
登入遠端server
ssh username@serverip

將public key 加入.ssh/authorized_keys  (我的cat 曾經動過手腳 alias 成 cat -n 害我卡了一整個晚上  哭哭)
cat .ssh/id_rsa.pub >> .ssh/authorized_keys 

這樣子就可以 key 認證登入, 不需輸入密碼.


重開遠端server ssh
Restarted sshd via synoservicectl --restart sshd and by restarting whole NAS.
or
rebooot

2016年5月24日 星期二

linux server 記事 ubuntu 16.04LTS

家裡退休的筆電閒了下了,因此打算架個 linux server 來玩玩
在這邊紀錄一下架設日誌,過程,供日後參考。

安裝版本為 ubuntu 16.04 LTS desktop x64 english



*更新軟體
apt-get update
apt-get upgrade

*備份
rsync + ssh + crontab

1.先處理免密碼登入的 RSA key

2.編輯vim backup_script.ssh 內容只有一行
rsync -av /* username@serverip::NetBackup/ngulinux/ --rsh='ssh -i userPrivateKey' --exclude={/dev/*,/home/username/.cache/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}

不知道為何我上面的指令可以直接 單run script 執行沒問題,但是加到crontab時 ㄍ--exclude 指令沒起到作用,因此只好把此指令拔掉將除外的檔案塞到額外的檔案,作法大概是
rsync -av /* username@serverip::NetBackup/ngulinux/ --exclude-from='/root/rsync_bk/excludeList'  --rsh='ssh -i userPrivateKey' -

然後建立一個檔案叫 excludeList 在路徑上
檔案的寫法大概是
/dev/
/proc/
/sys/
/tmp/
/run/
/mnt/
/media/
/lost+foun/
.cache/
google-chrome/
/var/tmp/
/var/log/

大概說明一下
/dev/    代表略過此目錄(連目錄都不產生)
/dev/*  複製此目錄但是略過此目錄下所有檔案
dev/     所有檔案或目錄的名稱的任意位置包含 dev 的都略過

3.將backup_script.ssh 加進crontab
vim /etc/crontab

* * * * * root /bin/sh /cronfiles/rsync.sh
(分 時 日月 周) (執行者) (執行shell) (script)

10 5    * * *   root    /root/rsync_bk/rsync.sh >> /var/log/rsync.log 2>&1

收割
#/etc/init.d/cron restart


*遠端桌面
1.anydesk  http://anydesk.com/remote-desktop
2.teamviewer  https://www.teamviewer.com/
3.VNC xrdp
ref.http://programingman.blogspot.tw/search/label/raspberry

*文字介面開機

vim /etc/default/grub

修改成以下參數

#GRUB_HIDDEN_TIMEOUT=0
#GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=3
GRUB_CMDLINE_LINUX_DEFAULT="text"
GRUB_CMDLINE_LINUX="text"
GRUB_TERMINAL=console

開啟多人模式
sudo systemctl enable multi-user.target --force 
sudo systemctl set-default multi-user.target
更新
update-grub

若要開啟x-window 不知道為何我的 startx 無效
需要
service lightdm restart
or 
 /etc/init.d/lightdm restart
才可以再開啟x-window

到此告一段落,我做出的效果差不多就是開機為tty1 文字模式
遠端可以隨時xrdp 回來x-window (使用Windows),當server 有問題時也可以使用x-window 來控制

在這邊不得不推崇一下 Teamviewer,發現使用teamviewer 設定好後不用登入到 x-window 畫面
在TTY1 純文字下就可以連進來下 command 不知道怎麼做的,有點厲害
若在TTY1 下使用 service lightdm restart ,畫面也會自動轉為x-window , 是個蠻棒的環境

所以在我的環境下
1.可以使用xrdp 直接遠端進我的 Sever 桌面 (不需要 service lightdm restart)
2.可以使用teamviewer 進來下 service lightdm restart 後直接轉成我的桌面
3.SSH 近來我的server

完成,媽呀 因為我的是筆電,每次重開機時只要系統偵測到是蓋著的就自動休眠

# 按下電源 預設行為為關機
HandlePowerKey=poweroff
 # 按下暫停
 HandleSuspendKey=suspend 
# 按下休眠 
HandleHibernateKey=hibernate
 # 闔上螢幕
# HandleLidSwitch=suspend
HandleLidSwitch=ignore

vim /etc/systemd/logind.conf

*必備軟體
sudo apt-get install vim
sudo apt-get install tmux

chewing
upnpc
openssh-server

*wake-on-Lan 網路喚醒

#ethtool interfaceName
查看 這兩個參數
Supports Wake-on: pg
Wake-on: d

d為disable 的意思  g為magic packet 可以喚醒的意思

使用指令將 Wake-on 改為 g

#ethtool -s eth0 wol g

之後就可以關機試試看效果了
另一台電腦使用
wakelan or wakeonlan 之類的指令試試看可不可以喚醒

wakeonlan YOUR_TARGET_MAC -b 192.168.0.255

-b 為指定brocast packet  因為 中間的router or switch 若因為arp timeout 有可能default 的行為不是flooding 而是drop 使用brocast packet 是比較保險的做法

其中ethtool -s eth0 wol g 只有一次性,因此需要用你所想的道的方式設定他always on
ex.加入排程 crontab

way2. 使用nmcli 指令設定
# nmcli con show
NAME    UUID                                  TYPE            DEVICE
enp9s0  e33fd8e4-bf42-4652-8a85-55e4ebc49d24  802-3-ethernet  enp9s0

查看wol 是否有開啟
# nmcli c show "enp9s0" | grep 802-3-ethernet.wake-on-lan
802-3-ethernet.wake-on-lan:             80 (broadcast, magic)
802-3-ethernet.wake-on-lan-password:    --

修改成接收broadcast and magic paacket 
nmcli c modify "enp9s0" 802-3-ethernet.wake-on-lan magic,broadcast

(後記:在我的環境兩種方式都設定過了還是不work ,發包的magic packet 沒有錯誤,另一台電腦可以順立wol,因此猜測應該是硬體支援的問題,
先暫時放棄此功能,原本想法是有要連進來再利用gateway 將server 喚醒避免不必要的耗電,畢竟當server 是不太會關機的)


*sudo 免密碼

因為常常在 sudo 我的密碼又很大一串,所以索性用個免密碼sudo 這樣就不用先轉成 root 在做事

修改方式大概為

(舊版方式)
在username最後的一個ALL 前加入 NOPASSWD
username ALL=(ALL) NOPASSWD: ALL
username ALL=(ALL:ALL) NOPASSWD: ALL

上面兩種用法就看你的系統是用哪種語法跟著原本的方式寫就是了

注意若此檔修改錯誤會造成無法使用 sudo 指令,因此語法要注意一下
最好的方式是使用visudo 指令修改,會幫你檢查與法有無錯誤

更新 新版方式更安全些寫在/etc/sudoers.d

vi /etc/sudoers.d/nopasswd4sudo
输入 
yourusername ALL=(ALL) NOPASSWD : ALL
ESC :wq!




*SAMBA 參考 (點我)

但是瑞凡  我失敗了,不知道為何 在我的Raspberry mate 15.04 是成功的 在16.04失敗,也不知從何Debug 起 ,先擱著好了。

# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares. This will share each
# user's home directory as \\server\username
[homes]
comment = Home Directories
browseable = yes

結果是這段的 [homes] 沒有打開,ㄍㄋㄋ  搞了我一個晚上















2016年3月30日 星期三

Synology 6.0 root passwd

DSM 在6.0有做一些修正導致無法使用root 登入(安全性考量 default ban 掉root),或者是拿不到權限

比較簡單的作法是使用管理者帳號登入然後下 (這邊加進sudo 的功能)
sudo -i
即可變成root 登入

但是還是無法直接使用root 登入,若sudo 失效系統就GG

所以還是有其他方法改成直接使用root登入如下


After getting the DSM 6.0 upgrade, I’ve become unable to login as root using SSH, even though I’ve been able to do it before the upgrade (DSM 5.5 or something like that).
The solution:
1. SSH to machine as admin user.
2. Enter command “sudo su” and providing admin password.
3. Enter command “synouser --setpw root yourPasswd “.
Now I’m able to logon as root using SSH again, and I didn’t have to mess with telnet.

這是更新的經驗是,以後synology 不要亂進大版(我從DSM5.2 -> DSM6.0),否環境可能會被改到,還要再弄一次。

/etc 下的chmod 權限不要亂改,我為了讓權限打開 修改此檔暫時將 /etc/sudoers權限改為chmod 777 ,然後就發生悲劇了,使用sudo 指令時都出現

sudo: /etc/sudoers is world writable
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin

意思是任何人都可以修改此檔,系統認為此檔無效,因此sudo 不吃此檔案
想改回來需要sudo chmod 但是又先執行了sudo 引此就卡死了,然後系統又不能使用使用root登入將此檔的權限改回來,整個系統差點GG

還好在/opt/bin/ 底下我也有安裝sudo 使用此執行的改回來就正常了。

2016年1月28日 星期四

ubuntu samba user home directors

Ref.http://linux.vbird.org/linux_server/0370samba.php

sudo apt-get install samba
sudo apt-get install python-glade2 system-config-samba

sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
vim /etc/samba/smb.conf
 

更改以下項目
#======================= Share Definitions =======================

# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares. This will share each
# user's home directory as \\server\username
[homes]
   comment = Home Directories
   browseable = yes

# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
   read only = no

# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
   create mask = 0775

# Directory creation mask is set to 0700 for security reasons. If you want to
# create dirs. with group=rw permissions, set next parameter to 0775.
directory mask = 0775

# By default, \\server\username shares can be connected to by anyone
# with access to the samba server.
# Un-comment the following parameter to make sure that only "username"
# can connect to \\server\username
# This might need tweaking when using external authentication schemes
   valid users = %S


創造samba 帳戶和密碼
#smbpasswd -a "username"

enable user
#smbpasswd -e username


重啟
#service smbd restart

使用windows 登入

連接網路磁碟機
\\server\username



=> 避免掛載新磁碟機到各user底下後無法access

sudo vi /etc/samba/smb.conf 在 [global] tag中加入

follow symlinks = yes 

unix extensions = no 

wide links = yes

2016年1月25日 星期一

raspberry ubuntu mate 15.10

##先前準備
SDFormatter
Win32DiskImager

##安裝下載 (請安裝英文版)
https://ubuntu-mate.org/raspberry-pi/


Re-size file system
sudo fdisk /dev/mmcblk0

Delete the second partition (d, 2), then re-create it using the defaults (n, p, 2, enter, enter), then write and exit (w). Reboot the system, then:sudo resize2fs /dev/mmcblk0p2

查看硬碟狀況
df -h

##設定WIFI 且開機自動連線
修改 vim /etc/network/interfacesauto wlan0
allow-hotplup wlan0
iface wlan0 inet static
        address 192.168.0.102
        netmask 255.255.255.0
        gateway 192.168.0.1
        wpa-ssid "SSID"
        wpa-psk "PASSWD"
dns-nameservers 168.95.192.1 8.8.8.8

or
iface wlan0 inet dhcp

ref.http://gsyan888.blogspot.tw/2013/04/raspberry-pi-wireless-network.html

##更新軟體
apt-get update
apt-get upgrade


##關閉圖形介面
graphical enable/disable

console開啟圖形介面
startx

##root遠端登入
1. 修改 /etc/ssh/sshd_config
# vim /etc/ssh/sshd_config
把 PermitRootLogin without-password 前面加上 # 註解
#PermitRootLogin without-password
加入下面這一行
PermitRootLogin yes
2. 重新啟動電腦或重新啟動 ssh Server
# sync;sync;sync;sync;reboot

##安裝必要軟體
*編輯器
apt-get install vim

*多功軟體
apt-get install tmux

*windows to linux 遠端桌面
apt-get install xrdp



##定期動備份至NAS (way1)
在此使用方式為掛載網路硬碟NAS,再使用resync 同步

*掛載 ref.
mkdir /mnt/mountDirector
mount -t cifs //{ip address}/{share} -o username={username},password={password} /mnt/mountDirector/
/mnt/mountDirector/ 為 mount point,取消用 umount /mnt/mountDirector/
編碼可加上iocharset=utf8這種寫法

*RSYNC 備份軟體 (src改為 / (root director)在此的Dest改為/mnt/mountDirector/)
WiKi
rsync -av /src/foo /dest 會在 /dest 下產生一個 foo 的資料夾,表示複製這個資料夾。
rsync -av /src/foo/ /dest 則不會在 /dest 下產生一個 foo 的資料夾,表示複製這個資料夾下

*定期備份

#vim cronfiles/rsync.sh
rsync -av / /mnt/synology_215j/raspberry_ubuntu/

plz try:
rsync -av /* /path/to/backup/folder --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}

#vim /etc/crontabm


##定期動備份至NAS (way2)
後來覺得way1 不好用,rsync 常常會跳出error  權限不足之累的,改用ssh 就好一點只要先設好key 的話是頗方便的,請參考
http://programingman.blogspot.tw/2016/05/linux-server.html



最後加進cronfile

  *   *   *   *   *  root /bin/sh /cronfiles/rsync.sh
(分 時 日月 周) (執行者)   (執行shell)   (script)


*收割
#/etc/init.d/cron restart

2016年1月15日 星期五

svn 常用




SVN(Subversion)是一个自由、开源的项目源代码版本控制工具。目前,绝大多数开源软件和企业代码管理,都使用SVN作为代码版本管理软件。
Subversion将文件存放在中心版本库里,这个版本库很像一个普通的文件服务器。不同的是,它可以记录每一次文件和目录的修改情况,这样就可以在需要的回滚时,将数据恢复到以前的版本,并可以查看数据的更改细节。
SVN 官方网址:Apache Subversion
SVN 服务器配置:安装SVN服务器

一、 SVN常用命令
1、将文件checkout到本地目录
svn checkout path(path是服务器上的目录)
简写:svn co

2、往版本库中添加新的文件
svn add file

3、将改动的文件提交到版本库
svn commit -m “LogMessage” [-N] [--no-unlock] PATH(如果选择了保持锁,就使用–no-unlock开关)
简写:svn ci

4、加锁/解锁
svn lock -m “LockMessage” [--force] PATH
svn unlock PATH

5、更新到某个版本
svn update -r m path
简写:svn up

6、查看文件或者目录状态
1)svn status path(目录下的文件和子目录的状态,正常状态不显示)
2)svn status -v path(显示文件和子目录状态)
简写:svn st

7、删除文件
svn delete path -m “delete test fle”
简写:svn (del, remove, rm)

8、查看日志
svn log path

9、查看文件详细信息
svn info path

10、比较差异
svn diff path(将修改的文件与基础版本比较)
svn diff -r m:n path(对版本m和版本n比较差异)
简写:svn di

11、将两个版本之间的差异合并到当前文件
svn merge -r m:n path

12、SVN 帮助
svn help
svn help ci


二、 SVN不常用命令
13、版本库下的文件和目录列表
  svn list path    显示path目录下的所有属于版本库的文件和目录简写:svn ls

14、创建纳入版本控制下的新目录
svn mkdir: 创建纳入版本控制下的新目录。
用法:
1、mkdir PATH...
每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增调度,以待下一次的提交。
2、mkdir URL... 创建版本控制的目录。
每个以URL指定的目录,都会透过立即提交于仓库中创建。在这两个情况下,所有的中间目录都必须事先存在。

15、恢复本地修改
svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。
用法: revert PATH... 注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复被删除的目录

16、代码库URL变更
svn switch (sw): 更新工作副本至不同的URL。
用法:
1、switch URL [PATH]    
更新你的工作副本,映射到一个新的URL,其行为跟“svn update”很像,也会将      服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的方法。
2、switch --relocate FROM TO [PATH...] 
改写工作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动     (比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同一目录时使用     这个命令更新工作副本与仓库的对应关系。

17、解决冲突
svn resolved: 移除工作副本的目录或文件的“冲突”状态。
用法: resolved PATH... 注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的相关文件,然后让 PATH 可以再次提交。

18、输出指定文件或URL的内容。
svn cat 目标[@版本]...如果指定了版本,将从指定的版本开始查找。 svn cat -r PREV filename > filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)

三、 SVN其它命令
虽然不像本章先前讨论过的那些命令那么常用,但是有时你也需要这些命令。

svn cleanup
当Subversion修改你的工作副本时(或者任何在.svn中的信息),它尝试尽可能做到安全。在改变一个工作副本前,Subversion把它的意 图写到一个日志文件中。接下来它执行日志文件中的命令来应用要求的修改。最后,Subversion删除日志文件。从架构上来说,这与一个日志文件系统 (journaled filesystem)类似。如果一个 Subversion操作被打断(例如,进程被杀掉了,或机器当掉了)了,日志文件仍在硬盘上。重新执行日志文件,Subversion可以完成先前开始 的操作,这样你的工作副本能回到一个可靠的状态。

以下是svn cleanup所做的:它搜索你的工作副本并执行所有遗留的日志,在这过程中删除锁。如果Subversion曾告诉你你的工作副本的一部分被“锁定”了,那么你应该执行这个命令。另外, svn status会在锁定的项前显示L。

$ svn status
L    somedir
M   somedir/foo.c

$ svn cleanup
$ svn status
M      somedir/foo.c

svn import
使用svn import是把未版本化的文件树复制到资料库的快速办法,它需要创建一个临时目录。

$ svnadmin create /usr/local/svn/newrepos
$ svn import mytree file:///usr/local/svn/newrepos/some/project
Adding         mytree/foo.c
Adding         mytree/bar.c
Adding         mytree/subdir
Adding         mytree/subdir/quux.h

Committed revision 1.

上面的例子把在some/project目录下mytree目录的内容复制到资料库中。

$ svn list file:///usr/local/svn/newrepos/some/project
bar.c
foo.c
subdir/

注意在导入完成后,原来的树没有被转化成一个工作副本。为了开始工作,你仍然需要svn checkout这个树的一个新的工作副本。


四、SVN 常用命令一览表
命令功能使用格式
checkout检出svn  co  URL
up更新到当前URL的末端svn  up
switch更新到某一tag/branchsvn  switch  (tag/分支)URL
add增加svn  add  文件名
rm删除文件svn  rm 文件名
删除目录svn  rm 目录名
diff与base版本(最后检出或者更新到的版本)对比svn  diff
与版本库中最新版本对比svn  diff  -r  head
当前工作副本,两个版本之间对比svn  diff  -r  reversion1:reversion2
版本库中任意两个tag做对比svn   diff    (tag1)URL    (tag2)URL
ci提交svn ci -m "commit log"
log查看当前工作副本logsvn  log
只查看指定版本的logsvn  log  -r
打印log所有附加信息svn  log  -v
查看当前tag/branch版本详情svn  log --stop-on-copy -v
info查看当前工作副本所在URLsvn  info
status查看工作副本的状态svn st
查看文件的taglistsvn命令不支持,可执行cs taglist
tag新增tagsvn cp . (tag)URL
删除tagsvn rm (tag)URL -m "commit log"
覆盖已经存在的tag不支持
分支开发创建branchsvn  cp  (基线版本)URL (分支)URL  -m "commit log"
删除branchsvn rm (分支)URL   -m "commit log"
同步svn co (主干)URL
cd ~/wc
svn merge (主干)URL (待同步tag)URL
svn ci -m "commit log"
svn cp (主干)URL (以_PD_BL_MAIN结尾的tagURL -m"commit log"
合并svn co (合并目标)URL
cd ~/wc
svn merge (基线版本tag)URL  (上线tag)URL
svn ci -m "commit log"
svn cp (合并目标)URL (上线tag_MERGE_的tag对应)URL -m"commit log"


SVN实例
删除目录下所有的 .svn 隐藏子目录
find . -name ".svn" -print0 | xargs -0 rm -rf

tags打分支
svn  cp  trunk/    tags/platform_2011.11.11    (或 svn  cp  http://192.168.1.100/platform/trunk/    http://192.168.1.100/platform/tags/platform_2011.11.11
svn  ci  -m  "svn  cp  trunk/    tags/platform_2011.11.11"         // 提交,并给出提交记录(-m  "svn  cp  trunk/    tags/platform_2011.11.11")

svn 改名
svn  mv  platform_2011.11.11   platform_20111111
svn  ci  -m  "svn  mv  platform_2011.11.11   platform_20111111"        // 提交

svn directory is missing
1) svn up missingDirName
2) svn del missingDirName
3) svn ci

svn chech version
svn  co  http://192.168.1.100/platform/branch  -r  12  platform_branch_v12

svn log
svn  log  http://192.168.1.100/platform/branch  -l10              // svn  文字注释log
svn  log  http://192.168.1.100/platform/branch  -l10  -v          // svn 文字注释log + 文件更新log(增,删,改)

svn diff -r  v_1 : v_2 svn_path
svn diff -r 200:201 test.php

查看svn版本
svnserve --version

ubuntu 安装svn 1.7、1.8
当前 ubuntu 12.04 中的 svn 版本为 1.6,这个版本会在每个子目录新建一个.svn 的目录保存版本文件,很不爽。找到一个第三方编译的 ubuntu 源:

1) 打开source.list源:
sudo vi /etc/apt/sources.list   
2) 添加源
deb http://ppa.launchpad.net/dominik-stadler/subversion-1.7/ubuntu precise main
deb-src http://ppa.launchpad.net/dominik-stadler/subversion-1.7/ubuntu precise main
3) 执行安装命令
sudo apt-get install subversion


参考推荐:






SVN在线代码托管工具


openwrt OpenWRT UCI API的使用

ref. http://www.tamabc.com/article/1543.html

OpenWRT UCI API的使用


OpenWRT UCI API的使用
UCI 是OpenWRT爲實現配置集中化而引入的一個軟件包, 通過修改UCI,可以實現對OpenWRT的絕對部分配置的修改.LUCI(OpenWRT 的WEB配置界面)也是通過讀UCI配置文件的操作來實現用戶對路由的配置的。通過掌握UCI的API的使用,可以方便地將您的軟件的配置接口集成到LUCI中.

LUCI配置文件簡介


LUCI的配置文件一般存儲在 /etc/config目錄下。比如網絡配置文件則是 /etc/config/network 無線的配置文件是 /etc/config/wireless. 跟多配置文件的含義參考官方 WIKI

基本概念


UCI上下文: struct uci_context *
包(Package): 一個包對應一個UCI格式的文件.類型是 struct uci_package *
節(Section): 一個配置文件的節點. 類型是 struct uci_list *
值(Value):一個節下面可能包含多個值 一個值具有一個名字.
UCI配置文件的基本操作.

首先您需要引入頭文件


#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <uci.h>


static struct uci_context * ctx = NULL; //定義一個UCI上下文的靜態變量.
/*********************************************
*   載入配置文件,並遍曆Section.
*/
bool load_config()
{
    struct uci_package * pkg = NULL;
    struct uci_element *e;


    ctx = uci_alloc_context(); // 申請一個UCI上下文.
    if (UCI_OK != uci_load(ctx, UCI_CONFIG_FILE, &pkg))
        goto cleanup; //如果打開UCI文件失敗,則跳到末尾 清理 UCI 上下文.


    /*遍曆UCI的每一個節*/
    uci_foreach_element(&pkg->sections, e)
    {
        struct uci_section *s = uci_to_section(e);
        // 將一個 element 轉換爲 section類型, 如果節點有名字,則 s->anonymous 爲 false.
        // 此時通過 s->e->name 來獲取.
        // 此時 您可以通過 uci_lookup_option()來獲取 當前節下的一個值.
        if (NULL != (value = uci_lookup_option_string(ctx, s, "ipaddr")))
        {
            ip = strdup(value) //如果您想持有該變量值,一定要拷貝一份。當 pkg銷毀後value的內存會被釋放。
        }
        // 如果您不確定是 string類型 可以先使用 uci_lookup_option() 函數得到Option 然後再判斷.
        // Option 的類型有 UCI_TYPE_STRING 和 UCI_TYPE_LIST 兩種.


    }
    uci_unload(ctx, pkg); // 釋放 pkg 
cleanup:
    uci_free_context(ctx);
    ctx = NULL;
}

遍曆一個UCI_TYPE_LIST 類型.


加入現在有一個如下的配置文件:
    config  "server" "webserver"
        list    "index" "index.html"
        list    "index" "index.php"
        list    "index" "default.html"

代碼片:
// s 爲 section.
struct uci_option * o = uci_lookup_option(ctx, s, "index");
if ((NULL != o) && (UCI_TYPE_LIST == o->type)) //o存在 且 類型是 UCI_TYPE_LIST則可以繼續.
{
    struct uci_element *e;
    uci_foreach_element(&o->v.list, e)
    {
        //這裏會循環遍曆 list
        // e->name 的值依次是 index.html, index.php, default.html
    }
}

寫配置


UCI提供了一個簡潔的辦法來操作配置信息,例如有一個配置文件
#文件名: testconfig
config  'servver'
    option  'value' '123' # 我們想修改 'value' 的值爲 '456'

代碼如下:
struct uci_context * ctx = uci_alloc_context(); //申請上下文
struct uci_ptr ptr ={
    .package = "config",
    .section = "servver",
    .option = "value",
    .value = "256",
};
uci_set(_ctx,&ptr); //寫入配置
uci_commit(_ctx, &ptr.p, false); //提交保存更改
uci_unload(_ctx,ptr.p); //卸載包


uci_free_context(ctx); //釋放上下文

依照上面的例子,我們可以舉一反三, uci_ptr 用來指定信息.而是用uci_set則是寫入信息.同類的函數有如下幾個: 針對list的操作:
    uci_add_list()  // 添加一個list 值
    uci_del_list()  // 刪除一個list 值
    uci_delete()    // 刪除一個option值