tmuxで、セッション開始時に特定のプログラムを起動させたい場合。
その場合は、ユーザのホームディレクトリ直下にある「~/.tmux.conf」に以下の一行を追加してやればよい。
●~/.tmux.conf
set-option -g default-command コマンドPATH
これで、tmuxの起動と同時に指定されたコマンドが実行される。

tmuxで、セッション開始時に特定のプログラムを起動させたい場合。
その場合は、ユーザのホームディレクトリ直下にある「~/.tmux.conf」に以下の一行を追加してやればよい。
●~/.tmux.conf
set-option -g default-command コマンドPATH
これで、tmuxの起動と同時に指定されたコマンドが実行される。
John the Ripperとかでパスワードクラックをする際に使われる辞書ファイルなのだが、ある程度パスワードに使われている文字が推測できている状況の場合、通常の辞書ファイルだと余分なパスワードもいっぱいあって処理に時間がかかる。「ある程度推測できているパスワードだけど、文字の順番入れ替えたりしてるだけのリストがほしい」という時は、パスワードなどのワードリスト生成用のツールである『crunch』コマンドというものを使うといいようだ。
ペネトレーションテスト時に使われるものなので、KaliLinuxには最初から入っている様子。CentOS などにインストールをする場合は、以下のコマンドを実行する。
wget https://downloads.sourceforge.net/project/crunch-wordlist/crunch-wordlist/crunch-3.6.tgz tar xzvf crunch-3.6.tgz cd crunch-3.6 make && make install
Debian/UbuntuやOS Xの場合は、以下でもインストールできる。
sudo apt install -y crunch # Debian/Ubuntu系の場合 brew install crunch # OS Xの場合
使い方は簡単で、以下のようにコマンドを実行する。
crunch <出力文字列の最短の長さ> <出力文字列の最長の長さ> [options] [<使用する文字列>]
主なオプションは以下。
基本的には、-pあたりを覚えておけばよいだろう。
例えば、-pを使うことで文字の順序を入れ替えただけの値を得ることができる。
[root@BS-PUB-CENT7-01 ~]# crunch 3 3 -p abc Crunch will now generate approximately the following amount of data: 24 bytes 0 MB 0 GB 0 TB 0 PB Crunch will now generate the following number of lines: 6 abc acb bac bca cab cba
これがないと、渡した文字すべての組み合わせを総当たりで出力してしまう。
以下のようなワンライナーで、ブレース展開使って無理やりやるのと変わらなくなるので注意。
TEST=$(echo test) && eval echo $(eval echo $(echo $TEST | xargs -I@ sh -c 'echo \"{$(echo @ | sed "s/./&,/g;s/.$//g")}\"{$(echo @ | sed "s/./,/g;s/.$//g")}') | tr -d ' ' ) | tr ' ' '\n' | sort | uniq | wc -l
ネットで調べものをしていたところ、Linuxのシステムやハードウェアの情報についてわかりやすく出力してくれる『Inxi』コマンドなるものを見かけたので、ちょっとインストールしてみることにした。
インストールコマンドは以下。yumやaptからインストール可能だ。
sudo yum install inxi sudo apt install inxi
インストール後は、普通にコマンドを実行してやればよい。
オプションなしでコマンドを実行することで、CPUやメモリ容量など、基本的なハードウェア情報を得ることができる。
inxi
blacknon@BS-PUB-UBUNTU-01:~$ inxi CPU~Dual core Common KVM (-MCP-) speed~2266 MHz (max) Kernel~4.4.0-57-generic x86_64 Up~6 days Mem~264.7/1998.2MB HDD~42.9GB(12.6% used) Procs~144 Client~Shell inxi~2.2.35
その他、以下のようなオプションを付与することで諸々のハードウェア情報を得ることができる。
出力情報を見る限り、個人的にはdmidecodeよりは見やすいと思う。
コンソール上で、ランダムな数字を出力させたいというのがあったので、少し調べてみた。
結構いろいろな方法があるようだ。
bashでは、環境変数「$RANDOM」を用いることで0~32767までの数字をランダムに出力させることができる。
0から数えるので、+100とかで指定すると0~99までしか出力しないので注意。
echo $RANDOM # 0~32767までの範囲で出力する echo $((RANDOM%+101)) # 0~100までの範囲で出力する echo $((RANDOM%100+101)) # 100~200までの範囲で出力する
[root@BS-PUB-CENT7-01 ~]# echo $RANDOM # 0~32767までの範囲で出力する 1885 [root@BS-PUB-CENT7-01 ~]# echo $RANDOM # 0~32767までの範囲で出力する 10607 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%+101)) # 0~100までの範囲で出力する 76 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%+101)) # 0~100までの範囲で出力する 22 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%100+101)) # 100~200までの範囲で出力する 107 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%100+101)) # 100~200までの範囲で出力する 138
複数の数字を得る場合は、以下のようにコマンドを実行することで指定回数繰り返し、ランダムな数字を複数出力させることができる。
yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定
[root@BS-PUB-CENT7-01 ~]# yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定 42 48 51 8 77 54 60 2 14 97
「$RANDOM」に比べるとちょっと扱いづらいけど、「/dev/urandom」もしくは「/dev/random」を読み込むことで、ランダムな文字列・値を取得することができる。そのままcatなどで開いても扱えないので、odで加工するのが一般的。2のべき乗の範囲の値が取得されるようなので、範囲をちゃんと指定する場合はさらに加工が必要になりそう。
とりあえず、以下のようにコマンドを実行することで0~100までの値を取得できる。
echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))
[root@BS-PUB-CENT7-01 ~]# yes 'echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))' | head -10 | bash 70 31 0 44 30 30 29 7 14 68
seqのように利用できるBSD系のコマンドでjotというのがあるが、これには「-r」というランダムな値を出力するオプションが付いている。Debian/Ubuntu系であればaptでインストールできる。
以下のようにjotコマンドを実行することで、0~100までのランダムな値を10個出力させている。
jot -r 10 0 100
blacknon@BS-PUB-UBUNTU-01:~$ jot -r 10 0 100 61 50 44 54 55 88 77 5 20 71
jotがないorインストールできない場合、とりあえずseqとshufで似たようなことはできる(処理効率悪いと思うけど)。
とりあえず、以下のようにコマンドを実行することで0~100のランダムな値を1個得ることができる。
seq 0 100 | shuf | head -1
blacknon@BS-PUB-UBUNTU-01:~$ seq 0 100 | shuf | head -1 42 blacknon@BS-PUB-UBUNTU-01:~$ yes 'seq 0 100 | shuf | head -1' | head -10 | bash 20 60 14 3 20 64 24 0 33 64
awkのrand関数を用いることで、ランダムな数字を取得できる。srand()で初期化が必要なのだが、これは現在時刻(秒)を元に計算しているため、1秒経過しないとランダムな値でも同じ値が出力されてしまうので注意。
awk 'BEGIN{srand(1);print int(rand()*100)}'
blacknon@BS-PUB-UBUNTU-01:~$ awk 'BEGIN{srand();print int(rand()*100)}' 88 blacknon@BS-PUB-UBUNTU-01:~$ awk 'BEGIN{srand();print int(rand()*100)}' 60 blacknon@BS-PUB-UBUNTU-01:~$ # 連続で実行しても、秒が経過するまでは同じ値が出力される。 blacknon@BS-PUB-UBUNTU-01:~$ yes "awk 'BEGIN{srand();print int(rand()*100)}'" | head -10 | bash 70 70 70 70 70 70 70 70 70 70
Perlで出力する場合はこんな感じ。
perl -e 'printf ("%d\n",int(rand($MAX - $MIN)))' perl -e 'foreach $i (1..n) {printf ("%d\n",int(rand(MAX - MIN)))}'
blacknon@BS-PUB-UBUNTU-01:~$ perl -e 'printf ("%d\n",int(rand(100 - 0)))' 82 blacknon@BS-PUB-UBUNTU-01:~$ perl -e 'foreach $i (1..10) {printf ("%d\n",int(rand(100 - 0)))}' 6 90 53 1 25 68 93 97 9 82
Rubyでやる場合はこんなん。
ruby -e 'printf("%d\n",Random.rand(MIN...MAX))' ruby -e 'ran= 0..n;ran.each{printf("%d\n",Random.rand(MIN...MAX))}'
blacknon@BS-PUB-UBUNTU-01:~$ ruby -e 'printf("%d\n",Random.rand(0...100))' 71 blacknon@BS-PUB-UBUNTU-01:~$ ruby -e 'ran= 0..10;ran.each{printf("%d\n",Random.rand(0...100))}' 78 71 18 12 49 92 32 7 72 35 73
Pythonの場合。
python -c 'from random import randint; print(randint(MIN,MAX))' python -c 'from random import randint; print "\n".join(map(str,[randint(MIN,MAX) for p in range(0,n)]))'
blacknon@BS-PUB-UBUNTU-01:~$ python -c 'from random import randint; print(randint(0,100))' 91 blacknon@BS-PUB-UBUNTU-01:~$ python -c 'from random import randint; print "\n".join(map(str,[randint(0,100) for p in range(0,10)]))' 93 49 23 9 29 72 23 53 34 53
なんか、某所で見にくい・加工しにくいと話題になってた『内閣府の「国民の祝日」CSV』について、シェル芸を使って加工して少し見やすくしたので備忘として残しておく(使うことはないだろうけど)。
このデータ、確かにそのままだと扱いにくいけど加工自体はそこまで難易度の高いものではないみたい。コンソール上で見やすくするため、CSVではなくTSVにして出力してみる(CSVにしたきゃ、awkのとこにある「\t」を「,」に変えればいいだけだし)。
以下、Linuxで実行できるコマンド。
文字コード・改行コードの変換にnkfコマンドが必要になるので、環境にインストールしておくこと。
curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{print $2"\t"$1}'
blacknon@BS-PUB-DEVELOP:~$ curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{print $2"\t"$1}' 2016/1/11 成人の日 2016/2/11 建国記念の日 2016/3/20 春分の日 2016/4/29 昭和の日 2016/5/3 憲法記念日 2016/5/4 みどりの日 2016/5/5 こどもの日 2016/7/18 海の日 2016/8/11 山の日 2016/9/19 敬老の日 2016/9/22 秋分の日 2016/10/10 体育の日 2016/11/3 文化の日 2016/11/23 勤労感謝の日 2016/12/23 天皇誕生日 2017/1/9 成人の日 2017/2/11 建国記念の日 2017/3/20 春分の日 2017/4/29 昭和の日 2017/5/3 憲法記念日 2017/5/4 みどりの日 2017/5/5 こどもの日 2017/7/17 海の日 2017/8/11 山の日 2017/9/18 敬老の日 2017/9/23 秋分の日 2017/10/9 体育の日 2017/11/3 文化の日 2017/11/23 勤労感謝の日 2017/12/23 天皇誕生日 2018/1/8 成人の日 2018/2/11 建国記念の日 2018/3/21 春分の日 2018/4/29 昭和の日 2018/5/3 憲法記念日 2018/5/4 みどりの日 2018/5/5 こどもの日 2018/7/16 海の日 2018/8/11 山の日 2018/9/17 敬老の日 2018/9/23 秋分の日 2018/10/8 体育の日 2018/11/3 文化の日 2018/11/23 勤労感謝の日 2018/12/23 天皇誕生日
せっかくなので、日付に曜日もつけてみる。
curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{c="date -d \""$2"\" +%a";c|getline t;print $2"("t")\t"$1}'
blacknon@BS-PUB-DEVELOP:~$ curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{c="date -d \""$2"\" +%a";c|getline t;print $2"("t")\t"$1}' 2016/1/11(月) 成人の日 2016/2/11(木) 建国記念の日 2016/3/20(日) 春分の日 2016/4/29(金) 昭和の日 2016/5/3(火) 憲法記念日 2016/5/4(水) みどりの日 2016/5/5(木) こどもの日 2016/7/18(月) 海の日 2016/8/11(木) 山の日 2016/9/19(月) 敬老の日 2016/9/22(木) 秋分の日 2016/10/10(月) 体育の日 2016/11/3(木) 文化の日 2016/11/23(水) 勤労感謝の日 2016/12/23(金) 天皇誕生日 2017/1/9(月) 成人の日 2017/2/11(土) 建国記念の日 2017/3/20(月) 春分の日 2017/4/29(土) 昭和の日 2017/5/3(水) 憲法記念日 2017/5/4(木) みどりの日 2017/5/5(金) こどもの日 2017/7/17(月) 海の日 2017/8/11(金) 山の日 2017/9/18(月) 敬老の日 2017/9/23(土) 秋分の日 2017/10/9(月) 体育の日 2017/11/3(金) 文化の日 2017/11/23(木) 勤労感謝の日 2017/12/23(土) 天皇誕生日 2018/1/8(月) 成人の日 2018/2/11(日) 建国記念の日 2018/3/21(水) 春分の日 2018/4/29(日) 昭和の日 2018/5/3(木) 憲法記念日 2018/5/4(金) みどりの日 2018/5/5(土) こどもの日 2018/7/16(月) 海の日 2018/8/11(土) 山の日 2018/9/17(月) 敬老の日 2018/9/23(日) 秋分の日 2018/10/8(月) 体育の日 2018/11/3(土) 文化の日 2018/11/23(金) 勤労感謝の日 2018/12/23(日) 天皇誕生日
…なんか嫌な予感がする。
曜日を少し加工しやすいようにして、集計してみよう。
# 曜日をタブ区切りで2列目にする curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{c="date -d \""$2"\" +%a";c|getline t;print $2"\t"t"曜日\t"$1}' # 更に曜日別集計(わかりやすいよう改行入れる) curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv \ | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{c="date -d \""$2"\" +%a";c|getline t;print $2"\t"t"曜日\t"$1}' \ | awk -F'[/\t]' '{print $1" "$4}' | sort | uniq -c | grep -E -e '^.*[土,日]曜日' -e $
blacknon@BS-PUB-DEVELOP:~$ curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{c="date -d \""$2"\" +%a";c|getline t;print $2"\t"t"曜日\t"$1}' 2016/1/11 月曜日 成人の日 2016/2/11 木曜日 建国記念の日 2016/3/20 日曜日 春分の日 2016/4/29 金曜日 昭和の日 2016/5/3 火曜日 憲法記念日 2016/5/4 水曜日 みどりの日 2016/5/5 木曜日 こどもの日 2016/7/18 月曜日 海の日 2016/8/11 木曜日 山の日 2016/9/19 月曜日 敬老の日 2016/9/22 木曜日 秋分の日 2016/10/10 月曜日 体育の日 2016/11/3 木曜日 文化の日 2016/11/23 水曜日 勤労感謝の日 2016/12/23 金曜日 天皇誕生日 2017/1/9 月曜日 成人の日 2017/2/11 土曜日 建国記念の日 2017/3/20 月曜日 春分の日 2017/4/29 土曜日 昭和の日 2017/5/3 水曜日 憲法記念日 2017/5/4 木曜日 みどりの日 2017/5/5 金曜日 こどもの日 2017/7/17 月曜日 海の日 2017/8/11 金曜日 山の日 2017/9/18 月曜日 敬老の日 2017/9/23 土曜日 秋分の日 2017/10/9 月曜日 体育の日 2017/11/3 金曜日 文化の日 2017/11/23 木曜日 勤労感謝の日 2017/12/23 土曜日 天皇誕生日 2018/1/8 月曜日 成人の日 2018/2/11 日曜日 建国記念の日 2018/3/21 水曜日 春分の日 2018/4/29 日曜日 昭和の日 2018/5/3 木曜日 憲法記念日 2018/5/4 金曜日 みどりの日 2018/5/5 土曜日 こどもの日 2018/7/16 月曜日 海の日 2018/8/11 土曜日 山の日 2018/9/17 月曜日 敬老の日 2018/9/23 日曜日 秋分の日 2018/10/8 月曜日 体育の日 2018/11/3 土曜日 文化の日 2018/11/23 金曜日 勤労感謝の日 2018/12/23 日曜日 天皇誕生日 blacknon@BS-PUB-DEVELOP:~$ blacknon@BS-PUB-DEVELOP:~$ # 更に曜日別集計(わかりやすいよう改行入れる) blacknon@BS-PUB-DEVELOP:~$ curl -s http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv \ > | nkf -Luw | sed '1,3d;$d;s/,/ /g' | xargs -n2 | sort -Vk2 | awk '{c="date -d \""$2"\" +%a";c|getline t;print $2"\t"t"曜日\t"$1}' \ > | awk -F'[/\t]' '{print $1" "$4}' | sort | uniq -c | grep -E -e '^.*[土,日]曜日' -e $ 1 2016 火曜日 2 2016 金曜日 4 2016 月曜日 2 2016 水曜日 1 2016 日曜日 5 2016 木曜日 3 2017 金曜日 5 2017 月曜日 1 2017 水曜日 4 2017 土曜日 2 2017 木曜日 2 2018 金曜日 4 2018 月曜日 1 2018 水曜日 3 2018 土曜日 4 2018 日曜日 1 2018 木曜日
…2016年、とても恵まれた奇跡の年だったのですね。
2017年の祝日が結構土曜日と被ってるのは知ってたけど、まさか来年もとは…。悲しい…。
日曜は振替になるからいいけど、土曜日も振替休日欲しいなぁ。
あと、大晦日って国民の祝日じゃないんだ。知らなかった。
で、今回はこの程度のデータ量や難易度、更にあんまり使わなそうなデータだったからいいけど、これと同じことをもっと重要、かつ大きなデータとかでやられるのはどうかなと思う。
これ、文字コードや改行コードから推測するとWindowsで作ったんじゃないかな(高い確率でExcelから生成されてる気がする)。正直、データとしてはよろしい…とは言えないので、次は改善して欲しいなぁと。
sshの鍵認証で、特定のカギのみをrootで許可してやり、一般ユーザに勝手に追加させないようにしたいなぁ…という話があり、やり方を考えてみた。
で、当初は『.ssh/authorized_keys』ファイルの所有者をrootに変えてやり、一般ユーザには読み込み権限だけを与えてしまえばいいかなと思ったのだが、どうもそれではうまくいかない。というのも、『.ssh/』ディレクトリの所有者はその一般ユーザになるので、『.ssh/authorized_keys』を削除して作り変えてしまえるためだ。
[test@BS-PUB-CENT7-01 ~]$ ls -al .ssh/ 合計 4 drwx------. 2 test test 28 2月 23 00:15 . drwx------. 3 test test 90 2月 23 00:15 .. -rw-r--r--. 1 root root 405 2月 23 00:15 authorized_keys [test@BS-PUB-CENT7-01 ~]$ echo test > .ssh/authorized_keys -bash: .ssh/authorized_keys: 許可がありません [test@BS-PUB-CENT7-01 ~]$ echo test >> .ssh/authorized_keys -bash: .ssh/authorized_keys: 許可がありません [test@BS-PUB-CENT7-01 ~]$ cp .ssh/authorized_keys{,.bk} [test@BS-PUB-CENT7-01 ~]$ rm .ssh/authorized_keys rm: 書き込み保護されたファイル 通常ファイル `.ssh/authorized_keys' を削除しますか?y [test@BS-PUB-CENT7-01 ~]$ cp .ssh/authorized_keys{.bk,} [test@BS-PUB-CENT7-01 ~]$ ls -la .ssh/ 合計 8 drwx------. 2 test test 53 2月 23 00:16 . drwx------. 3 test test 90 2月 23 00:15 .. -rw-r--r--. 1 test test 405 2月 23 00:16 authorized_keys -rw-r--r--. 1 test test 405 2月 23 00:16 authorized_keys.bk
だからと言って、『.ssh』フォルダの所有者を変更してしまっては鍵認証でのログインはできない。ディレクトリの所有者なので、スティッキービットを設定しても意味がない。
ではどうすればいいのか?とりあえず、たとえディレクトリの所有者であろうとも『.ssh/authorized_keys』の削除を行えなければ回避できるはずだ。
という訳で、ファイルの所有者をrootにした状態で、さらにchattrを使って拡張属性で削除不可(追記のみ可能)にしてやればいけるのではないかと考えた。
所有者がrootであれば、一般ユーザでchattrを使ってもフラグを変更できないため、何もできないはずだ。
というわけで、さっそくやってみた。
[root@BS-PUB-CENT7-01 ~]# ls -la /home/test/.ssh/authorized_keys -rw-r--r--. 1 root root 405 2月 23 00:16 /home/test/.ssh/authorized_keys [root@BS-PUB-CENT7-01 ~]# [root@BS-PUB-CENT7-01 ~]# # chattr +a で追記のみ可能にする [root@BS-PUB-CENT7-01 ~]# chattr +a /home/test/.ssh/authorized_keys [root@BS-PUB-CENT7-01 ~]# lsattr /home/test/.ssh/authorized_keys -----a---------- /home/test/.ssh/authorized_keys [root@BS-PUB-CENT7-01 ~]# [root@BS-PUB-CENT7-01 ~]# su - test 最終ログイン: 2017/02/23 (木) 00:23:34 JST日時 pts/1 [test@BS-PUB-CENT7-01 ~]$ [test@BS-PUB-CENT7-01 ~]$ ls -la .ssh/authorized_keys -rw-r--r--. 1 root root 405 2月 23 00:16 .ssh/authorized_keys [test@BS-PUB-CENT7-01 ~]$ ls -la .ssh 合計 4 drwx------. 2 test test 28 2月 23 00:22 . drwx------. 3 test test 90 2月 23 00:15 .. -rw-r--r--. 1 root root 405 2月 23 00:16 authorized_keys [test@BS-PUB-CENT7-01 ~]$ [test@BS-PUB-CENT7-01 ~]$ # 追記のみ可能だが、書き込み権限がないので何もできない [test@BS-PUB-CENT7-01 ~]$ echo aaa > .ssh/authorized_keys -bash: .ssh/authorized_keys: 許可がありません [test@BS-PUB-CENT7-01 ~]$ echo aaa >> .ssh/authorized_keys -bash: .ssh/authorized_keys: 許可がありません [test@BS-PUB-CENT7-01 ~]$ [test@BS-PUB-CENT7-01 ~]$ # 追記のみ可能なので、ファイルの削除もできない [test@BS-PUB-CENT7-01 ~]$ rm -rf .ssh/authorized_keys rm: `.ssh/authorized_keys' を削除できません: 許可されていない操作です
もちろん、ssh-copy-idなどでも鍵の追加が行えないようになった。
blacknon@BS-PUB-DEVELOP:~$ ssh-copy-id -i test test@BS-PUB-CENT7-01 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "test.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys sh: .ssh/authorized_keys: 許可がありません
注意点としては、拡張属性で定義してしまってるので、rootであっても追記しか行えない状態になったということだろうか。
編集を行う場合は、一度属性を解除してから編集する必要があるので注意。
先日、2017年02月24日よりプレミアムフライデーなるモノが始まった。これは、毎月の最終金曜日は15時退社にして余暇を作ることで個人消費を増やし、景気促進を促すという経産省主導の消費喚起のプログラムなのだが、あいにくと導入している企業は0.1%前後とかで、今の時点だとプレミアムな企業にしか適用されてないようだ(プレミアムな企業だったら給料も高いので、消費喚起という意味ではまぁ間違ってない…のか?景気対策としての効果は疑問だけど、まぁ結果を見てからかなぁ…)。
で、じゃあ今年のプレミアムフライデーは何日なのかをコンソール上で出力させてってみよう。日付関係の処理を行うといえばdateコマンドなので、今回はこれらを利用する。
さて、dateコマンドといえば、「-d」オプションで”last friday”とか指定すれば前回の金曜日の日付を取得してくれるのだが、この指定方法は日付を直接指定してから行えない。つまり、現在時刻からみての前回の金曜日が出力されてしまう。
blacknon@BS-PUB-UBUNTU-01:~$ date -d 'last friday' 2017年 2月 24日 金曜日 00:00:00 JST blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ # 直接指定した日付が優先されてしまう blacknon@BS-PUB-UBUNTU-01:~$ date -d '2017/02/01 last friday' 2017年 2月 1日 水曜日 00:00:00 JST
でも、この-dで前回の金曜日を取得したい…。そんなときは、結構前にも触れたことのあるlibfaketimeをインストールするとよいだろう。これを使うことで、dateコマンドが認識する時刻をfaketimeで指定した時刻にだますことが可能になる。faketimeは前に紹介した時から結構進化しており、以下のようにyumやaptでインストールが可能となっている。
yum --enablerepo epel install libfaketime apt install faketime brew install libfaketime
で、あとはdateコマンドの実行前にfaketimeで適当な日付を指定してやる。
faketime 2017-01-01 date -d 'last friday'
[root@BS-PUB-CENT7-01 ~]# faketime 2017-01-01 date -d 'last friday' 2016年 12月 30日 金曜日 00:00:00 JST
これを応用してやれば、以下のように記述することで各月の最終金曜日、プレミアムフライデーを出力させることができる。
printf 'faketime %s date -d "last fri"\n' {17{02..12},1801}01|sh
[root@BS-PUB-CENT7-01 ~]# # ブレース展開はネストさせることができるので、これを利用して2017/02~2018/01の01日の日付を生成する [root@BS-PUB-CENT7-01 ~]# printf "%s\n" 20{17/{02..12},18/01}/01 2017/02/01 2017/03/01 2017/04/01 2017/05/01 2017/06/01 2017/07/01 2017/08/01 2017/09/01 2017/10/01 2017/11/01 2017/12/01 2018/01/01 [root@BS-PUB-CENT7-01 ~]# [root@BS-PUB-CENT7-01 ~]# # 上と組み合わせて、printfで実行するコマンドを一覧で出力させる [root@BS-PUB-CENT7-01 ~]# printf 'faketime %s date -d "last fri"\n' 20{17/{02..12},18/01}/01 faketime 2017/02/01 date -d "last fri" faketime 2017/03/01 date -d "last fri" faketime 2017/04/01 date -d "last fri" faketime 2017/05/01 date -d "last fri" faketime 2017/06/01 date -d "last fri" faketime 2017/07/01 date -d "last fri" faketime 2017/08/01 date -d "last fri" faketime 2017/09/01 date -d "last fri" faketime 2017/10/01 date -d "last fri" faketime 2017/11/01 date -d "last fri" faketime 2017/12/01 date -d "last fri" faketime 2018/01/01 date -d "last fri" [root@BS-PUB-CENT7-01 ~]# [root@BS-PUB-CENT7-01 ~]# # 生成したコマンドをパイプでシェルに渡して実行させる [root@BS-PUB-CENT7-01 ~]# printf 'faketime %s date -d "last fri"\n' 20{17/{02..12},18/01}/01 | sh 2017年 1月 27日 金曜日 00:00:00 JST 2017年 2月 24日 金曜日 00:00:00 JST 2017年 3月 31日 金曜日 00:00:00 JST 2017年 4月 28日 金曜日 00:00:00 JST 2017年 5月 26日 金曜日 00:00:00 JST 2017年 6月 30日 金曜日 00:00:00 JST 2017年 7月 28日 金曜日 00:00:00 JST 2017年 8月 25日 金曜日 00:00:00 JST 2017年 9月 29日 金曜日 00:00:00 JST 2017年 10月 27日 金曜日 00:00:00 JST 2017年 11月 24日 金曜日 00:00:00 JST 2017年 12月 29日 金曜日 00:00:00 JST
さて、じゃあFaketimeを使わない場合だとどうすればよいのか。
dateでは出力フォーマットを指定できるので、それを使って月の金曜日で最後の日付を抽出してやればよい。
とりあえず、こんな感じ。
echo 17{12..01}{31..01}$'\n' | date -f - "+%F %m %w" 2>&- | awk '$3~ /5/ && !a[$2$3]++{print $1}' | tac
分解するとこんな感じ。
# ブレース展開で(存在しない日付を含む)1年間すべての日付を取得する echo 2017/{12..01}/{31..01}$'\n' # パイプで渡してやり、"YYYY-MM-DD MM 曜日(番号(金曜は5))"の形式で出力する。なお、「2>&-」は「2>/dev/null」と同様の動作をする echo 2017/{12..01}/{31..01}$'\n' | date -f - "+%F %m %w" 2>&- # awkを使って、3列目(曜日)が5のもののみを抽出する echo 2017/{12..01}/{31..01}$'\n' | date -f - "+%F %m %w" 2>&- | awk '$3~ /5/' # さらにawkに条件を追加して、2列目と3列目が同じものを以後表示させない echo 2017/{12..01}/{31..01}$'\n' | date -f - "+%F %m %w" 2>&- | awk '$3~ /5/ && !a[$2$3]++' # printで1列目のみを表示させるようにする echo 2017/{12..01}/{31..01}$'\n' | date -f - "+%F %m %w" 2>&- | awk '$3~ /5/ && !a[$2$3]++{print $1}' # 降順で日付を出力させていたので、tacで昇順にする echo 2017/{12..01}/{31..01}$'\n' | date -f - "+%F %m %w" 2>&- | awk '$3~ /5/ && !a[$2$3]++{print $1}' | tac
実行結果。
[root@BS-PUB-CENT7-01 ~]# echo 2017/{12..01}/{31..01}$'\n' | date -f - "+%F %m %w" 2>&- | awk '$3~ /5/ && !a[$2$3]++{print $1}' | tac 2017-01-27 2017-02-24 2017-03-31 2017-04-28 2017-05-26 2017-06-30 2017-07-28 2017-08-25 2017-09-29 2017-10-27 2017-11-24 2017-12-29
その他の解き方としては、@Heliac1999さんのweek数とかこっちのやり方、@ebanさんのこれとかこれがとても参考になる。
…プレミアムフライデー、効果はどうかわからないけど、一般的になれば早く帰れるのでありがたいですね。
よくbashやzshでシェル芸(ワンライナー)を書いてたりすると、標準エラー出力だけを/dev/nullに出力させたりといった処理を行う。
で、毎回いちいち/dev/nullとか指定するのもあれなんで、省略記述方法ないかなと思って調べてみたところ、Bash4以降だと結構記述方法が増えたようだ。個人的によく利用する記述の省略形だけピックアップして記述しておく。
標準エラー出力や標準出力、どっちかだけを非表示にさせたい場合だと「2>/dev/null」と記述して/dev/nullにリダイレクトさせるのだが、以下のようにも書けるようだ。
2>/dev/null 2>&-
blacknon@BS-PUB-UBUNTU-01:~$ ls -la aaa a ls: 'a' にアクセスできません: そのようなファイルやディレクトリはありません -rw-rw-r-- 1 blacknon blacknon 254 3月 13 2016 aaa blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ ls -la aaa a 2>/dev/null -rw-rw-r-- 1 blacknon blacknon 254 3月 13 2016 aaa blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ ls -la aaa a 2>&- -rw-rw-r-- 1 blacknon blacknon 254 3月 13 2016 aaa blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ ls -la \- ls: '-' にアクセスできません: そのようなファイルやディレクトリはありません
標準エラー出力も含めてパイプで次のコマンドに渡す場合。
以下のようにも記述できる。
2&>1 | Command ... |& Command ...
blacknon@BS-PUB-UBUNTU-01:~$ ls -la aaa a 2>&1 | grep -e ls -e $ ls: 'a' にアクセスできません: そのようなファイルやディレクトリはありません -rw-rw-r-- 1 blacknon blacknon 254 3月 13 2016 aaa blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ ls -la aaa a |& grep -e ls -e $ ls: 'a' にアクセスできません: そのようなファイルやディレクトリはありません -rw-rw-r-- 1 blacknon blacknon 254 3月 13 2016 aaa
同様の考え方で、「>&」で1,2ともにリダイレクトが行える。
「/dev/null」からリダイレクトをして空ファイルを作ったり中身を削除する場合。
こういった場合は、以下のようにも書けるようだ。「:」はヌルコマンドなので、それを利用すればよい。
cat /dev/null > Path : > Path
blacknon@BS-PUB-UBUNTU-01:~$ grep "" a_test{1,2}.txt a_test1.txt:test a_test2.txt:test blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ cat /dev/null > a_test1.txt blacknon@BS-PUB-UBUNTU-01:~$ cat a_test1.txt blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ : > a_test2.txt blacknon@BS-PUB-UBUNTU-01:~$ cat a_test2.txt
大体、こんなとこだろうか。
結構省略して書くことができるみたいだ。
【参考】
bashやzshで、historyに任意のコマンド…というか文字列を実行せずに追記したい場合。
それぞれ、以下のコマンドで行うことができるようだ。
history -s string # bashの場合 print -S string # zshの場合
blacknon@BS-PUB-UBUNTU-01:~$ history | tail
1628 rm -rf ./*
1629 clear
1630 ls
1631 echo aaa | tee test{01..20}.txt >& /dev/null
1632 ls
1633 grep '' ./*
1634 clear
1635 cd
1636 clear
1637 history | tail
blacknon@BS-PUB-UBUNTU-01:~$ history -s aaaa
blacknon@BS-PUB-UBUNTU-01:~$ history | tail
1630 ls
1631 echo aaa | tee test{01..20}.txt >& /dev/null
1632 ls
1633 grep '' ./*
1634 clear
1635 cd
1636 clear
1637 history | tail
1638 aaaa
1639 history | tail
特定のディレクトリ配下にあるファイルの行数とかを再帰的に取得する場合、wcコマンドが利用される場合が多いだろう。
wc -l $(find /PATH -type f)
blacknon@BS-PUB-UBUNTU-01:~/test_dir$ ls -la
合計 152
drwxrwxr-x 12 blacknon blacknon 4096 2月 25 16:42 .
drwxr-xr-x 15 blacknon blacknon 4096 2月 25 16:39 ..
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:41 00
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:41 10
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:41 20
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 30
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 40
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 50
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 60
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 70
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 80
drwxrwxr-x 2 blacknon blacknon 4096 2月 25 16:42 90
-rw-rw-r-- 1 blacknon blacknon 102773 2月 25 16:42 text.txt
blacknon@BS-PUB-UBUNTU-01:~/test_dir$ wc -l $(find ./ -type f)
9344 ./40/test46.txt
9344 ./40/test47.txt
9344 ./40/test44.txt
9344 ./40/test48.txt
9344 ./40/test49.txt
~省略~
9344 ./80/test89.txt
9344 ./80/test82.txt
9344 ./80/test85.txt
9344 ./80/test83.txt
9344 ./text.txt
934400 合計
こんな感じでやれば、指定したディレクトリ配下にある各ファイルと合計の行数がわかる。
が、さらにその中身(ファイルの種類だったり、コメント行の行数だったり…)を把握する場合は、clocコマンドを利用すると楽だ。
インストールは、以下のコマンドで行える。
yum enablerepo=epel install cloc apt install cloc brew install cloc
インストール後は、普通に対象のディレクトリを引数として指定してやれば再帰的に確認してくれる。
出力例は以下。Golangとかでもちゃんと検知してくれる。
blacknon@BS-PUB-DEVELOP:~/go/src/github.com/blacknon/lssh$ cloc /home/blacknon/go/src 373 text files. 364 unique files. 779 files ignored. http://cloc.sourceforge.net v 1.60 T=2.05 s (161.7 files/s, 38455.4 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Go 309 8222 6908 55065 Assembly 15 613 390 7383 C 1 37 8 152 Python 1 15 1 94 YAML 3 0 0 32 make 1 5 0 14 C/C++ Header 1 2 5 1 vim script 1 0 0 1 ------------------------------------------------------------------------------- SUM: 332 8894 7312 62742 -------------------------------------------------------------------------------
出力フォーマットも種類があって、xmlやcsvで出力させることも可能。
いまだにステップ数とかで成果を見てるとこなんかでは結構便利かもしれない(たぶんまだ生き残っている)。
コンソール上で、コマンドの結果を複数のファイルに出力したいことがある。
そういった場合、残念ながらbashの場合、リダイレクトだと複数のファイルへ同時に書き込むといったことは難しい。じゃ、どうすればいいのかというと、teeコマンドであれば複数ファイルを指定できるので、それで対応する。
コマンド | tee ファイル1 ファイル2 ファイル3 ... >& /dev/null # 追記しない場合 コマンド | tee -a ファイル1 ファイル2 ファイル3 ... >& /dev/null # 追記する場合
blacknon@BS-PUB-UBUNTU-01:~/test_dir$ ls blacknon@BS-PUB-UBUNTU-01:~/test_dir$ echo aaa | tee test{01..20}.txt >& /dev/null blacknon@BS-PUB-UBUNTU-01:~/test_dir$ ls test01.txt test04.txt test07.txt test10.txt test13.txt test16.txt test19.txt test02.txt test05.txt test08.txt test11.txt test14.txt test17.txt test20.txt test03.txt test06.txt test09.txt test12.txt test15.txt test18.txt blacknon@BS-PUB-UBUNTU-01:~/test_dir$ grep '' ./* ./test01.txt:aaa ./test02.txt:aaa ./test03.txt:aaa ./test04.txt:aaa ./test05.txt:aaa ./test06.txt:aaa ./test07.txt:aaa ./test08.txt:aaa ./test09.txt:aaa ./test10.txt:aaa ./test11.txt:aaa ./test12.txt:aaa ./test13.txt:aaa ./test14.txt:aaa ./test15.txt:aaa ./test16.txt:aaa ./test17.txt:aaa ./test18.txt:aaa ./test19.txt:aaa ./test20.txt:aaa
なお、zshの場合は以下のように複数ファイルを指定してのリダイレクトが可能になっている。
BS-PUB-UBUNTU-01% echo $0 zsh BS-PUB-UBUNTU-01% ls BS-PUB-UBUNTU-01% echo aaa > test_{01..20}.txt BS-PUB-UBUNTU-01% ls test_01.txt test_04.txt test_07.txt test_10.txt test_13.txt test_16.txt test_19.txt test_02.txt test_05.txt test_08.txt test_11.txt test_14.txt test_17.txt test_20.txt test_03.txt test_06.txt test_09.txt test_12.txt test_15.txt test_18.txt BS-PUB-UBUNTU-01% grep "" test_* test_01.txt:aaa test_02.txt:aaa test_03.txt:aaa test_04.txt:aaa test_05.txt:aaa test_06.txt:aaa test_07.txt:aaa test_08.txt:aaa test_09.txt:aaa test_10.txt:aaa test_11.txt:aaa test_12.txt:aaa test_13.txt:aaa test_14.txt:aaa test_15.txt:aaa test_16.txt:aaa test_17.txt:aaa test_18.txt:aaa test_19.txt:aaa test_20.txt:aaa
Apacheのアクセスログやエラーログだが、デフォルトではSyslogは経由しない。
これらをSyslogを使って管理する場合、httpd.confに設定の追加が必要になる。
設定自体は簡単で、CustomLog/ErrorLogの設定に対して、パイプで繋げてloggerでSyslogに流すだけだ。
以下、設定の記述例(VirtualHostとか設定してると記述先のファイルも変わるので、自分の環境に合わせて記述すること)。CentOS 7で確認をしている。
●/etc/httpd/conf/httpd.conf
CustomLog "|/usr/bin/logger -p local5.info -t httpd_access" combined ErrorLog "|/usr/bin/logger -p local6.info -t httpd_error"
次に、rsyslog側でログの出力先を設定する。
リモートに転送するのであればそのように記述してやればよい。
●/etc/rsyslog.d/httpd.conf
local5.* /var/log/httpd/access_log local6.* /var/log/httpd/error_log
さらに、今の設定のままだと/var/log/messagesにも同様のログが出力されてしまうので、/etc/rsyslog.confでmessagesへのログ出力設定に追記をする。
*.info;mail.none;authpriv.none;cron.none;local5.none;local6.none;
/var/log/messages
以上で設定は完了。
あとは、サービスの再起動をして設定を適用すればよい。
Nginxのログをsyslogで管理する場合、Niginx 1.7.1以降であればaccess_logおよびerror_logがSyslogをサポートするようになっている。
2017年3月現在、aptや(Epel経由にはなるが)yumでインストールできるNginxは1.7.1以降になるので、その前提で進めていく。
設定自体は簡単で、Nginxの設定ファイルでaccess_log/error_logの設定を以下のように書き換えてやればよい。
ただ、ローカル内のSyslogへ転送する場合でもUDP経由で送る必要がある(上にtcpで直接リモートのサーバには転送できない)ので、事前にrsyslogの設定でudpからのログを受信するよう設定しておくこと。
●/etc/nginx/nginx.conf(ローカルのrsyslogに送る場合)
http { ... access_log syslog:server=127.0.0.1:514,facility=local7,tag=nginx,severity=info; ...
あとはまぁ、もろもろrsyslogの設定するだけなので割愛。
【参考】
CentOSやUbuntuといった主要ディストリだと、Syslogにはrsyslogが使われている(ので、rsyslogがよく使われていると思う)。
でまぁ、rsyslogでlocalファシリティ(local5.infoとか)の設定をして、ファシリティ別に別ファイルにログを送るようにrsyslogで設定する際、以下の記述をしてないと「/var/log/messages」とか「/var/log/syslog」にもログが飛んでしまう。
*.info;mail.none;authpriv.none;cron.none;local5.none;local6.none;ファシリティ名.none;
/var/log/messages
これで、/var/log/messagesに対象のファシリティのログが転送されないようになったはずだ。
Twitterでそういうのを試みてる人がいて、できるみたいだったので備忘。
bash/zshだと、『$’AsciiCode’』で記述してやるとアスキーコードをその場で直接展開してくれるらしい(知らなかった…)。
[root@BS-PUB-CENT7-01 ~]# echo $'\x6c\x6f\x67\x67\x65\x72\x20\x27\x48\x65\x6c\x6c\x6f\x27' logger 'Hello'
で、これをそのまま実行するとコマンドが実行できるのかというと、どうもそうではないらしい。
教えていただいた内容によると、アスキーコードから展開させた場合だと、その結果はシングルクォートで括られた状態で扱われるらしく、アスキーコードでスペースを指定しててもあまり意味がないらしい。なので、実行するにはevalを利用するか、もしくはスペースだけはアスキーコードから展開させず、そのまま記述してやるといいみたいだ。アスキーコードの中でシングルクォートを指定してる場合、エスケープされたことと同じになってしまうので、evalとは結果が少し違う。
eval $'\x6c\x6f\x67\x67\x65\x72\x20\x27\x48\x65\x6c\x6c\x6f\x27' $'\x6c\x6f\x67\x67\x65\x72' $'\x27\x48\x65\x6c\x6c\x6f\x27'
blacknon@BS-PUB-UBUNTU-01:~$ echo $'\x6c\x6f\x67\x67\x65\x72\x20\x27\x48\x65\x6c\x6c\x6f\x27' logger 'Hello' blacknon@BS-PUB-UBUNTU-01:~$ $'\x6c\x6f\x67\x67\x65\x72\x20\x27\x48\x65\x6c\x6c\x6f\x27' logger 'Hello': コマンドが見つかりません blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ eval $'\x6c\x6f\x67\x67\x65\x72\x20\x27\x48\x65\x6c\x6c\x6f\x27' blacknon@BS-PUB-UBUNTU-01:~$ $'\x6c\x6f\x67\x67\x65\x72' $'\x27\x48\x65\x6c\x6c\x6f\x27' blacknon@BS-PUB-UBUNTU-01:~$ tail -2 /var/log/syslog Feb 28 07:42:18 BS-PUB-UBUNTU-01 blacknon: Hello Feb 28 07:42:27 BS-PUB-UBUNTU-01 blacknon: 'Hello'
手動でこのアスキーコード出すのは面倒(スペースをそのまま使うのであればなお)なので、文字列からアスキーコードを生成する場合は以下のようにコマンドを実行してやればよいだろう。
echo -n 'echo abc' | od -An -tx1 | sed 's/ /\\x/g;s/[^ ][^ ]*/eval \$'\''&'\''/g' # eval方式で出力 echo -n 'echo abc' | od -An -tx1 | sed 's/ /\\x/g;s/\\x20/ /g;s/[^ ][^ ]*/\$'\''&'\''/g' # そのまま実行可能な形式で出力
blacknon@BS-PUB-UBUNTU-01:~$ echo -n 'echo abc' | od -An -tx1 | sed 's/ /\\x/g;s/[^ ][^ ]*/eval \$'\''&'\''/g' eval $'\x65\x63\x68\x6f\x20\x61\x62\x63' blacknon@BS-PUB-UBUNTU-01:~$ echo -n 'echo abc' | od -An -tx1 | sed 's/ /\\x/g;s/[^ ][^ ]*/eval \$'\''&'\''/g' | bash abc blacknon@BS-PUB-UBUNTU-01:~$ blacknon@BS-PUB-UBUNTU-01:~$ echo -n 'echo abc' | od -An -tx1 | sed 's/ /\\x/g;s/\\x20/ /g;s/[^ ][^ ]*/\$'\''&'\''/g' $'\x65\x63\x68\x6f' $'\x61\x62\x63' blacknon@BS-PUB-UBUNTU-01:~$ echo -n 'echo abc' | od -An -tx1 | sed 's/ /\\x/g;s/\\x20/ /g;s/[^ ][^ ]*/\$'\''&'\''/g' | bash abc
はー…
そもそも、こういったことをするという発想がなかったので、「できるんだなぁ…」という感想。
難読化という意味では確かに有用かもしれない…。読めない。
コンソール上でスペース区切りになっている各文字列をシングルクォーテーション・ダブルクォーテーションで囲みたいことがあったので、その対応について備忘。
以下のようにコマンドを実行することで、スペース区切りの各単語を囲むことができる。
sedで各単語を囲む場合、以下のようにコマンドを実行する。
sed 's/[^ ]\+/"&"/g' # ダブルクォーテーションの場合 sed 's/[^ ]\+/'\''&'\''/g' # シングルクォーテーションの場合
blacknon@BS-PUB-UBUNTU-01:~$ echo abc def 123 ABC | sed 's/[^ ]\+/"&"/g' "abc" "def" "123" "ABC" blacknon@BS-PUB-UBUNTU-01:~$ echo abc def 123 ABC | sed 's/[^ ]\+/'\''&'\''/g' 'abc' 'def' '123' 'ABC'
awkの場合だとこんな感じ。
awk '{for(i=1;i<=NF;i++)printf("\""$i"\" ")}END{printf("\n")}' # ダブルクォーテーションの場合 awk '{for(i=1;i<=NF;i++)printf("'\''"$i"'\'' ")}END{printf("\n")}' # シングルクォーテーションの場合
blacknon@BS-PUB-UBUNTU-01:~$ echo abc def ghi | awk '{for(i=1;i<=NF;i++)printf("\""$i"\" ")}END{printf("\n")}' "abc" "def" "ghi" blacknon@BS-PUB-UBUNTU-01:~$ echo abc def ghi | awk '{for(i=1;i<=NF;i++)printf("'\''"$i"'\'' ")}END{printf("\n")}' 'abc' 'def' 'ghi'
2017/03/03 23:00
@ebanさんに、awkでもgsubで&を使って、sedのように記述できると教えてもらった。(知らなかった…)
エスケープでもうまくできないか試してみたけど、なんか汚くなっちゃう。アスキーコードで指定するのがいいみたいだ。
echo abc def ghi | awk '{gsub(/[^ ]+/,"\x22&\x22");print}' echo abc def ghi | awk '{gsub(/[^ ]+/,"\x27&\x27");print}'
blacknon@BS-PUB-UBUNTU-01:~$ echo abc def ghi | awk '{gsub(/[^ ]+/,"\x22&\x22");print}' "abc" "def" "ghi" blacknon@BS-PUB-UBUNTU-01:~$ echo abc def ghi | awk '{gsub(/[^ ]+/,"\x27&\x27");print}' 'abc' 'def' 'ghi'
まぁ、なんとなく。
ちょっと前にはやってた、『響け!ユーフォミアム』の文字列をループで1文字づつずらしてくシェル芸なのだが、なんかこう…床屋の前にあるくるくる回ってるポールみたいな奴(サインポールっていうらしい)のようにアニメーションさせられないかなと思いついたので、とりあえずやってみた。わかりやすいよう、「響」だけgrepで色つけてる。
echo 響け!ユーフォニアム|gsed ':a;p;s/\(.\)\(.*\)/\2\1/;ba'|xargs -I@ bash -c 'clear;echo @|gsed -ne"p;s/\(.\)\(.*\)/\2\1/;#"{0..9}|grep --color=always 響;sleep 0.1' # MacOS Xの場合 echo 響け!ユーフォニアム|sed ':a;p;s/\(.\)\(.*\)/\2\1/;ba'|xargs -I@ bash -c 'clear;echo @|sed -ne"p;s/\(.\)\(.*\)/\2\1/;#"{0..9}|grep --color=always 響;sleep 0.1' # Linuxの場合
更に、先日のアスキーコードでの実行などを使って、難読化させてみた。
echo ZWNobyDpn7/jgZHvvIHjg6bjg7zjg5Xjgqnjg4vjgqLjg6B8Z3NlZCAnOmE7cDtzL1woLlwpXCguKlwpL1wyXDEvO2JhJ3x4YXJncyAtSUAgYmFzaCAtYyAnY2xlYXI7ZWNobyBAfGdzZWQgLW5lInA7cy9cKC5cKVwoLipcKS9cMlwxLzsjInswLi45fXxncmVwIC0tY29sb3I9YWx3YXlzIOmfvztzbGVlcCAwLjEnCg== | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x44' | $'\x73\x68' # MacOS X用 echo ZWNobyDpn7/jgZHvvIHjg6bjg7zjg5Xjgqnjg4vjgqLjg6B8c2VkICc6YTtwO3MvXCguXClcKC4qXCkvXDJcMS87YmEnfHhhcmdzIC1JQCBiYXNoIC1jICdjbGVhcjtlY2hvIEB8c2VkIC1uZSJwO3MvXCguXClcKC4qXCkvXDJcMS87IyJ7MC4uOX18Z3JlcCAtLWNvbG9yPWFsd2F5cyDpn787c2xlZXAgMC4xJwo= | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' | $'\x73\x68' # Linux用
前に触ったcoloutを使って、「響」だけじゃなく、各文字に色つけてカラフルに?してみたのもある。
(ちょっと描写遅いけど)
echo 響け!ユーフォニアム|sed ':a;p;s/\(.\)\(.*\)/\2\1/;ba'|xargs -I@ bash -c 'clear;echo @|sed -ne"p;s/\(.\)\(.*\)/\2\1/;#"{0..9}|colout "(響*)(け*)(!*)(ユ*)(ー*)(フ*)(ォ*)(ニ*)(ア*)(ム*)" 1,2,3,4,5,6,7,8,9,14;sleep 0.5'
会社で同僚と会話中、こういった話題になったので”そういや、どうやって取るんだろ”と思って調べてみた。
結果、専用のコマンドでどうにかするってのは厳しそうだったので、ipcalcおよびsipcalcを使って計算、取得させてみた。
ipcalc $(ip addr show en0 | awk '$1=="inet"{print $2}') | awk 'NR==5{print $2}' sipcalc en0 | awk -F- '/Network address/||/Network mask \(bits\)/{print $2}' | xargs | sed 's/ /\//g'
blacknon@BS-PUB-DEVELOP:~$ ipcalc $(ip addr show ens18 | awk '$1=="inet"{print $2}') | awk 'NR= =5{print $2}' 172.28.0.0/24 blacknon@BS-PUB-DEVELOP:~$ sipcalc ens18 | awk -F- '/Network address/||/Network mask \(bits\)/{ print $2}' | xargs | sed 's/ /\//g' 172.28.0.0/24
以前にも触れたことのある、HTML5の踏み台サーバであるApache Guacamole。ssh接続時のターミナル操作のログを記録することもできるため、今回はそれを行う。取得できるログは2種類で、「Typescript(テキストベース)」および「Screen Recording(動画で取得)」のパターン。当たり前ではあるのだが、テキストベースはsshやtelnetでしか取れない。
今回利用するGuacamoleのバージョンは0.9.9とする。0.9.9の場合、テキストやビデオでの操作ログの取得は簡単で、Webの設定画面から行える。
Guacamoleでは、接続先ごとにログを記録するかどうか、記録先のPATHやログ名の設定が行える。
[SETTINGS] > [Connections]から対象のサーバの設定画面を開いて、[PARAMETERS]で対象の設定を行う。以下の画面はssh接続の場合。
それぞれの設定項目は簡単で、以下のようになっている。
ちなみに、こちらにあるように配置先ディレクトリやファイル名には変数が利用できる。
残念ながら接続先のホスト名は変数で用意されていない様子。設定自体が接続先ごとに行われるから、それでどうにかするって感じだろうか。
というわけで、設定するログファイルの名称例としては、以下のようにするといいのかなと。
上記設定を保存後は、接続したら自動的にログが出力されるようになる。
ちなみに、Screen Recordingの場合は一度ファイルを変換してm4vにすると再生できる。
guacenc 対象の録画データファイルPATH
変換後は、管理者がどこかに保管しておいて、随時閲覧すればよいだろう。
テキストよりも容量が大きくなるはずなので、退避を的確にしないといけないが、RDPやVNC接続であったとしても操作を記録できるのは素晴らしい。
[amazonjs asin=”B01IT509F8″ locale=”JP” title=”改訂新版 情報セキュリティ内部監査の教科書 (NextPublishing)”
wgetやcurlなどで、よく利用するURLと言うのはあると思う。で、毎回historyから取ってくるのも面倒だなぁと思って調べてみたところ、コンソール上でよく使うURLをブックマークできるツール『Buku』というコマンドを見かけたので、ちょっと試してみた。
Python3で書かれているらしいので、事前に必要となるパッケージをインストールをしておく。
sudo apt install python3-cryptography python3-bs4 git sudo yum install python3-cryptography python3-bs4 git
前提となるパッケージインストール後、以下のコマンドを実行して『Buku』のインストールを行う。
git clone https://github.com/jarun/Buku/ cd Buku sudo make install
これでインストールができた。
さて、それでは実際に使ってみよう。
色々オプションがあるみたいなのだが、とりあえず以下を把握しておけばいいだろう。
buku -p # ブックマークリストを表示する buku -a URL # ブックマークを追加する buku -d N # 指定された番号のブックマークを削除する buku -u N # 指定された番号のブックマークをアップデートする
残念ながら指定されたブックマークのURLのみを得ることはできないようなので、curlなどと組み合わせる場合はawkなどを利用して抽出してやる必要があるみたいだ。
以下の例では、1番のブックマークに対してcurlでアクセスしている。
curl $(buku -p 1 -f 1 | awk '{print $2}')
使いようによっては便利そうなツールだ。