2018年10月18日 星期四

[Linux 常見問題] How to set a file size limit for a directory?

Source From Here 
Question 
I have a directory on my system which is used for a specific reason by applications and users, but I don't want its size to be allowed to exceed 2GB, is there a way of setting up some sort of limit which just doesn't allow the file size to exceed that or any other amount I decide to set for it in the future? When the size limit is exceeded it should undo the last change (though there should be an option to have it so that it just stops the operation and doesn't care if half a file was copied and left there) and then display a warning to the user. 

How-To 
Usual filesystem quota on ext4 is per-user/group, not per-directory. ZFS can sort-of set a directory quota, by creating a filesystem of a fixed size off a ZFS volume. A simple trick, though, is to create a 2GB file, create a filesystem on it, and mount it at the desired folder: 
$ touch 2gbarea 
$ truncate -s 2G 2gbarea 
$ mke2fs -t ext4 -F 2gbarea 
mke2fs 1.43.3 (04-Sep-2016) 
Discarding device blocks: done 
Creating filesystem with 524288 4k blocks and 131072 inodes 
Filesystem UUID: bf1b2ee8-a7df-4a57-9d05-a8b60323e2bf 
Superblock backups stored on blocks: 
32768, 98304, 163840, 229376, 294912 

Allocating group tables: done 
Writing inode tables: done 
Creating journal (16384 blocks): done 
Writing superblocks and filesystem accounting information: done 


$ sudo mount 2gbarea up 
$ df -h up 
Filesystem Size Used Avail Use% Mounted on 
/dev/loop0 2.0G 6.0M 1.8G 1% /home/muru/up

In any case, filesystem quotas (or methods like this) aren't as user friendly as you want. This method is one-way flexible, in that you can increase the size online, but decreasing it would be hard. 

The commands: 
* touch: touch 2gbarea creates an empty file named 2gbarea. 
* truncate: truncate is used to resize files (in this case, I resize the currently empty 2gbarea file to 2 GB using -s 2G). 
* mke2fs: mke2fs creates ext2/3/4 filesystems (in this case, ext4). 
* mount: mounts the filesystem on the given directory. 
* df is used to list filesystem usage.


2018年10月13日 星期六

[Linux 小學堂] SSH 免密碼登入

轉載自 這裡 
前言 : 
關於 SSH 免密碼登入,我的第一篇學習文章是參考 Tsung 的 ssh keygen 免輸入密碼. 他的文章很淺顯易懂,我依樣畫葫蘆就成功了. 但問題是公司的限制是必需要有 passphrase、Tsung 的文章並沒有解釋此部份、造成我不打密碼但還是得打 passphrase. 我決定花一些時間把這個原理徹底弄懂,並寫成一篇文章跟大家分享. 

基本流程說明 : 
1. 私密與公開金鑰 
以 SSH 登入任何主機都必需要打帳號、密碼,除了不方便、另外還增加了被竊取的風險有些軟體如 winscp 是可儲存的)。 
解決的方式就是使用金鑰產生器來產生一筆公開金鑰(Public Key)與私密金鑰(Private Key)對應做免密碼的登入. 使用者只需將公開金鑰的內容附加系統上特定的檔案中,以及在自己的環境指定好私密金鑰,系統在登入流程中即會自動對應,正確無誤即可登入. 讓整個登入流程快速且安全 

2. 金鑰種類 
但是對應並沒有想像中這麼簡單,就像是木門上只能裝喇吧鎖而無法裝大鎖,不同的主機所能使用的金鑰機制也有所不同 : SSH 有 Protocol 1 及 Protocol 2 兩種,常見金鑰編碼機制則有 RSA1、RSA2、以及 DSA 等三種. 

3. 保護金鑰的措施 
另外一個問題, 如果有人拿到了你的私密金鑰,就相當於他可以在你的主機為所欲為. 保護的措施就是使用 Passphrase(也可以不設)、私密金鑰的密碼,每次要用時就得輸入. 

4. Agent 機制 
有 Passphrase 保護當然是安全多了,但原本想用金鑰的好處就是可以省去每次打密碼的步驟,現在若每次又得打 Passphrase,這樣的好處就沒有了,可能還得多記一套密碼、增加打錯的可能性. 還好有 Agent 機制,他相當是你的管家、我們只要把鑰匙及 Passphrase 請他保管,在登入主機時他就會幫你解決輸入 Passphrase 的問題. 

一步一步教到會 : 
以下就只針對 Mac OSX 及 *nix 系統做介紹(若你是使用 Windows 中的 PuTTY,請先做完步驟一與二,再看這裡): 
步驟 1. 產生金鑰 
在 Command Line 中你可以使用 ssh-keygen 來產生各種類的金鑰,而我也會鼓勵大家一次把三種金鑰產生好,省得碰到不同系統麻煩. 
a. 產生 RSA 1 金鑰 
這種金鑰是給比較舊的系統,例如 FreeBSD 4 及以前的版本、是走 SSH Protocol 1 的,最好就使用 RSA 1 這種金鑰 : 
john@linux-tl0r:~> ssh-keygen -t rsa1
Generating public/private rsa1 key pair.
Enter file in which to save the key (/home/john/.ssh/identity): <按下Enter>
Enter passphrase (empty for no passphrase): <輸入你的 Passphrase, 或直接按下Enter 不使用 Passphrase>
Enter same passphrase again: <再次輸入Passphrase或按下Enter當不使用Passphrase>
Your identification has been saved in /home/john/.ssh/identity.
Your public key has been saved in /home/john/.ssh/identity.pub.
The key fingerprint is:
98:e0:ba:bf:8a:30:ef:03:f5:6a:fc:da:38:a2:d3:bc john@linux-tl0r
The key's randomart image is:
...(省略)...

b. 產生 RSA 2 金鑰 
比較新的系統,如 FreeBSD 5 及之後版本或 Linux,用 RSA 2 或 DSA 這兩種金鑰 : 
john@linux-tl0r:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/john/.ssh/id_rsa): <按下Enter>
Enter passphrase (empty for no passphrase): <輸入你的 Passphrase, 或直接按下Enter 不使用 Passphrase>
Enter same passphrase again: <再次輸入Passphrase或按下Enter當不使用Passphrase>
Your identification has been saved in /home/john/.ssh/id_rsa.
Your public key has been saved in /home/john/.ssh/id_rsa.pub.
The key fingerprint is:
70:1c:e5:16:29:0e:db:85:4d:1a:ad:cf:c5:a1:89:1a john@linux-tl0r
The key's randomart image is:
...(省略)...

c. 產生 DSA 金鑰 
john@linux-tl0r:~> ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/john/.ssh/id_dsa): <按下Enter>
Enter passphrase (empty for no passphrase): <輸入你的 Passphrase, 或直接按下Enter 不使用 Passphrase>
Enter same passphrase again: <再次輸入Passphrase或按下Enter當不使用Passphrase>
Your identification has been saved in /home/john/.ssh/id_dsa.
Your public key has been saved in /home/john/.ssh/id_dsa.pub.
The key fingerprint is:
f1:67:ed:3f:f6:fa:55:37:5a:b7:96:f5:6f:61:04:4f john@linux-tl0r
The key's randomart image is:
...(省略)...

經過這樣的程序,我們總共會有公私鑰共三對:RSA1 ( identity.pub / identity )、RSA2 ( id_rsa.pub / id_rsa )、及 ( id_dsa.pub / id_rsa )。 
我過去有一個錯誤的觀念,以為金鑰是對應系統的,所以在對每一台主機得另外產生一次. 事實上如果沒有特殊需求,你可以只用一份、用任一系統產生、並把這一份給保存好即可. 

步驟 2. 將公開金鑰放到主機 
你現在在自己的機器上已經有了三對金鑰,接下來我們要把公開的三隻 (*.pub) 放到我們要登入的主機上. 
john@linux-tl0r:~> scp ~/.ssh/*.pub max@192.168.0.192:~/.ssh/ <傳送 public key 到登入主機上>
max@192.168.0.192's password: <輸入max 密碼, 並按下 enter 結束>
id_dsa.pub 100% 605 0.6KB/s 00:00
id_rsa.pub 100% 397 0.4KB/s 00:00
identity.pub 100% 642 0.6KB/s 00:00

接著登入該系統,在沒設定好之前當然還是得乖乖打密碼 : 
john@linux-tl0r:~> ssh max@192.168.0.192 <登入遠端主機>
max@192.168.0.192's password: <輸入密碼後, 成功登入主機>

系統預設處理放置公鑰的檔案叫做 authorized_keys,所以我們要把剛剛所傳的公鑰附加到這個檔案中 : 
max@linux-tl0r:~> cat ~/.ssh/identity.pub >> ~/.ssh/authorized_keys <附加pub key 的內容到檔案 authorized_keys>
max@linux-tl0r:~> cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
max@linux-tl0r:~> cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
max@linux-tl0r:~> chmod 711 ~/.ssh <讓.ssh 目錄只有自己能讀/寫/進入>
max@linux-tl0r:~> chmod 644 ~/.ssh/authorized_keys

如果沒有意外,你登出再登入主機,當你有使用Passphrase時, 就會看到它請你輸入 Passphrase 的訊息. 

步驟 3. 設定 ssh-agent <給有設定Passphrase使用者> 
前面所提到,每次都要打 Passphrase 就太麻煩了,所以這裡要設定管家 ssh-agent、以保管私鑰及 Passphrase. 在你每次啟動 shell 後,請照這樣的方式來做 : 
a. 啟動 ssh-agent 
eval `ssh-agent -s`

b. 將私密金鑰交給 ssh-agent 保管:ssh-add 
我們將要用 ssh-add 來指定金鑰,如果你都照上面放預設的位置及相同的檔名,那就不用有任何的參數. 
ssh-add

接著會要求你設定輸入 passphrase,如果三個都一樣,就只要打一次 : 
Enter passphrase for /home/username/.ssh/id_rsa: <輸入你的 Passphrase>
Identity added: /home/username/.ssh/id_rsa (/home/username/.ssh/id_rsa)
Identity added: /home/username/.ssh/id_dsa (/home/username/.ssh/id_dsa)
Identity added: /home/username/.ssh/identity (username@username.com)

接著再試看看登入已經放好公鑰的主機,應該就可以不用密碼登入了 : 
max@linux-tl0r:~> exit <離開遠端主機>
john@linux-tl0r:~> ssh max@192.168.0.192 <登入遠端主機>
Last login: Wed Sep 29 09:34:52 2010 from 192.168.0.191
Have a lot of fun...
max@linux-tl0r:~> <不用密碼, 就可以成功登入遠端主機了>

公私鑰所需放的機器 : 
我的歸納是,在本機上你必需一直保有這兩份以便後續的再製。而公鑰整理成 authorized_keys,以後有新機器需要登入時一律傳此檔案上去做附加。 
而除了本機外,那些機器需要放私鑰呢?我的情況是最常用的那台開發機,因為你可能會利用他去 SSH 其它台機器。不然的話,應該減少私鑰的存放地點,以求安全. 

補充說明 : 
PuTTY 免密碼登入 
你在使用 PuTTY 嗎? 如果你還在每天打密碼做登入,那實在是遜掉了。這篇文章就是要教你怎麼設定 PuTTY 免登入!

鳥哥Linux 私房菜 : 遠端連線伺服器 Telnet / SSH / VNC / XDMCP / RSH 
一部連上 Internet 上面的您的個人主機,最重要的是什麼呢? 大概就是如何讓您自己可以連線進入自己的主機,並且進行所謂的『遠端操控』了吧! 也就是說,您可以在任何具有連上 Internet 的電腦中,以遠端連線軟體連上 Internet ,並藉由您主機上面的遠端連線伺服器軟體提供的功能,直接登入您的主機來進行操控的工作!此時,您將發現 Linux 有趣又好玩的地方囉!

設定 Debian/Ubuntu 不允許使用 root ssh 登入 

2018年10月9日 星期二

[ Python 常見問題 ] matplotlib - Modify tick label text

Source From Here 
Question 
I want to make some modifications to a few selected tick labels in a plot. For example, if I do: 
  1. label = axes.yaxis.get_major_ticks()[2].label  
  2. label.set_fontsize(size)  
  3. label.set_rotation('vertical')  
the font size and the orientation of the tick label is changed. However, if try: 
  1. label.set_text('Foo')  
the tick label is not modified. Also if I do: 
  1. print label.get_text()  
So how exactly can I modify the tick label text? 

How-To 
Caveat: Unless the ticklabels are already set to a string (as is usually the case in e.g. a boxplot), this will not work with any version of matplotlib newer than 1.1.0. If you're working from the current github master, this won't work. I'm not sure what the problem is yet... It may be an unintended change, or it may not be... 

Normally, you'd do something along these lines: 
  1. """  
  2. Simple demo of a scatter plot.  
  3. """  
  4. import numpy as np  
  5. import matplotlib.pyplot as plt  
  6.   
  7. fig, ax = plt.subplots()  
  8.   
  9. N = 50  
  10. x = np.random.rand(N)  
  11. y = np.random.rand(N)  
  12. colors = np.random.rand(N)  
  13. area = np.pi * (15 * np.random.rand(N))**2  # 0 to 15 point radii  
  14.   
  15. plt.scatter(x, y, s=area, c=colors, alpha=0.5)  
  16.   
  17. # We need to draw the canvas, otherwise the labels won't be positioned and   
  18. # won't have values yet.  
  19. fig.canvas.draw()  
  20. labels = [item.get_text() for item in ax.get_xticklabels()]  
  21. print("xtick labels: {}".format(labels))  
  22. labels[1] = 'Testing'  # The second x tick label text is modified to be "Testing"  
  23.   
  24. ax.set_xticklabels(labels)  
  25.   
  26. plt.show()  
Output: 

[ Python 常見問題 ] matplotlib - How to force the Y axis to only use integers in Matplotlib?

Source From Here 
Question 
I'm plotting a histogram using the matplotlib.pyplot module and I am wondering how I can force the y-axis labels to only show integers (e.g. 0, 1, 2, 3 etc.) and not decimals (e.g. 0., 0.5, 1., 1.5, 2. etc.). 

How-To 
If you have the y-data 
  1. y = [0., 0.51., 1.52., 2.5]  
You can use the maximum and minimum values of this data to create a list of natural numbers in this range. For example: 
  1. import math  
  2. print range(math.floor(min(y)), math.ceil(max(y))+1)  
which will yield: 
  1. [0123]  
You can then set the y tick mark locations (and labels) using matplotlib.pyplot.yticks
  1. yint = range(min(y), math.ceil(max(y))+1)  
  2.   
  3. matplotlib.pyplot.yticks(yint)  
For example, we have sample code below: 
  1. import matplotlib.pyplot as plt    
  2. import numpy as np  
  3. import math  
  4.   
  5. x = np.linspace(0106)    
  6. y = np.array([0., 0.51., 1.52., 2.5])    
  7. print("y={}".format(y))  
  8.   
  9. fig, ax = plt.subplots()  
  10.   
  11. plt.plot(x, y)    
  12.   
  13. plt.xlabel('time')    
  14. plt.ylabel('Some function of time')    
  15. plt.title("My cool chart")    
  16.   
  17. plt.show()  



With above suggestion, you can have new version below: 
  1. import matplotlib.pyplot as plt    
  2. import numpy as np  
  3. import math  
  4.   
  5. x = np.linspace(0106)    
  6. y = np.array([0., 0.51., 1.52., 2.5])    
  7. print("y={}".format(y))  
  8.   
  9. fig, ax = plt.subplots()  
  10.   
  11. plt.plot(x, y)    
  12.   
  13. plt.xlabel('time')    
  14. plt.ylabel('Some function of time')    
  15. plt.title("My cool chart")    
  16.   
  17. # Modify ytick labels  
  18. print("min={}; max={}".format(math.floor(min(y.tolist())), math.ceil(max(y.tolist()))))  
  19. yint = range(math.floor(min(y.tolist())), math.ceil(max(y.tolist()))+1)  
  20. plt.yticks(yint)  
  21.   
  22. plt.show()  
You can achieve your goal: 


Supplement 
FAQ - Modify tick label text

[Linux 常見問題] How to set a file size limit for a directory?

Source From   Here   Question   I   have a directory on my system which is used for a specific reason by applications and users , but I   d...