Skip to main content

Posts for year 2017

windows script host by jscript

スクリプトの呼び出し。 アイコンのダブルクリックや、アイコンへのドラッグ&ドロップでも起動できる。

cscript script.js //Nologo
wscript script.js //Nologo

メッセージの表示。cscript ... で実行するとターミナルに表示される。

WScript.Echo( "メッセージ" + foo);

バッチファイルを呼び出す

var openssl     = "C:\\Users\\public\\Documents\\bin\\openssl.exe";
var shell   = WScript.CreateObject("WScript.Shell");

try {
  oExec = shell.Exec( openssl + " version" );
  //oExec = shell.Exec( openssl + " --help" );
  while ( ! oExec.StdOut.AtEndOfStream ) {
    WScript.Echo(oExec.StdOut.readline());
  }
  while ( ! oExec.StdErr.AtEndOfStream ) {
    WScript.Echo(oExec.StdErr.readline());
  }
}
catch (e){ 
  WScript.Echo(e)
}

引数のぶんだけ繰り返して実行する

var objArgs = WScript.Arguments;
var fso     = new ActiveXObject("Scripting.FileSystemObject");
var file;

for (i = 0; i < objArgs.length; i++) {
  try {
    file = fso.GetFile( objArgs(i) );
    fin = fso.OpenTextFile(file, 1, false);
    while ( ! fin.AtEndOfStream ) {
      line = fin.readline();
      WScript.Echo(line);
    }
    fin.Close();
  }
  catch (e) {
    WScript.Echo(e);
  }
}

ファイルを開き一行ずつ読み込んで処理。

var objArgs = WScript.Arguments;
var fso     = new ActiveXObject("Scripting.FileSystemObject");
var file;
var fin;

for (i = 0; i < objArgs.length; i++) {
  try {
    file = fso.GetFile( objArgs(i) );
  }
  catch(e) {
    WScript.Echo(e);
    continue;
  }
  fin = fso.OpenTextFile(file, 1, false);
  while ( ! fin.AtEndOfStream ) {
      line = fin.readline();
      WScript.Echo(line);
  }
  fin.Close();
}

アクセスファイルを開き、マクロを呼び出す。

var dbfile='C:\\Users\\public\\Documents\\Database1.accdb';
var timeout = 500; // milliseconds
try {
  var AccessApp = new ActiveXObject( "Access.Application" );
  // AccessApp.Visible = true;
  WScript.Sleep( timeout );

  try {
    AccessApp.OpenCurrentDatabase( dbfile );
    WScript.Sleep( timeout );
    // マクロを実行する例
    // AccessApp.DoCmd.RunMacro( "マクロ名" );
  }
  catch(e) {
    WScript.Echo(e);
  }
  finally {
    AccessApp.CloseCurrentDatabase();
  }
}
catch(e) {
    WScript.Echo(e);
}
finally {
  AccessApp.Quit();
  AccessApp = null;
}

excel

var excelfile = "c:\\users\\public\\documents\\test.xlsm"
var updatelinks = true;
var readonly = true;

try {
  var ExcelApp = new ActiveXObject("Excel.Application");
  // ExcelApp.Visible = true;
  // ExcelApp.DisplayAlerts = true;

  try {
    // var book = ExcelApp.Workbooks.Open(excelfile);
    var book = ExcelApp.Workbooks.Open(excelfile, updatelinks, readonly);
    // マクロを実行する例
    ExcelApp.Run("マクロ名")

    // シートに記入して保存する例
    // var sheet = book.sheets(1);
    // sheet.Cells(2, 1).value = "message...";
    // book.Save();
  }
  catch(e) {
    WScript.Echo(e)
  }
  finally {
    book.Close();
  }
}
catch(e) {
  WScript.Echo(e)
}
finally {
  ExcelApp.Quit();
}

backup and restore openldap

backup

# systemctl stop slapd
slapcat > ldap.ldif
slapcat -b cn=config > ldap-config.ldif

restore

systemctl stop slapd
mv /etc/ldap/slapd.d{,.bak}
mv /var/lib/ldap{,.bak}
mkdir /etc/ldap/slapd.d
mkdir /var/lib/ldap
slapadd -n0 -F /etc/ldap/slapd.d -l ldap-config.ldif
slapadd -l ldap.ldif
chown openldap:openldap -R /etc/ldap/slapd.d
chown openldap:openldap -R /var/lib/ldap
systemctl start slapd

sample of simple bash scripts

ファイルバックアップスクリプト

引数に与えられたファイルを3ケタの連番をつけてコピーする。 まだいま一ついけてない。

gistの引用のテストをかねて。

git

オープンソースの分散型VCS。同種のアプリケーションと比較してgitが優れているところは、ユーザが多く情報が多いという点。

gitリポジトリの作成

cd myproject
git init
git add .
git status
git diff
git rm [-r] target # -rで、ディレクトリを削除
git commit -m "commit message"
git log

作業ディレクトリを持たない公開用リポジトリの作成

git init --bare
or
git clone --bare myproject myproject.git

git log
git branch

単純なリモート作業

git clone git://example.com/.../myproject.git # リポジトリのclone
cd myproject
:
git push [origin] [master] # 変更内容をpush

git pull # fetchしてmerge

ブランチを作成し作業対象とする

git branch master
git pull
git checkout -b mybranch
git branch

masterブランチにマージ。不要なブランチの削除

git checkout master
git merge mybranch
git branch -d mybranch

ブランチをリモートにpush

git push origin mybranch

ブランチをリモートからfetchして作業

git fetch origin
git branch -a
git checkout -b mybranch origin/mybranch # ブランチを作成してチェックアウト

リモートブランチの削除

git push origin :mybranch

change last commit

git add file
git commit --amend -m "commit message"
git push -f origin master

Stash the changes in a dirty working directory away

git stash
git stash list
git stash show -p stash@{0}

apply stash on top of the current working directory. and remove a stash from the list

git stash apply stash@{0}
git stash drop stash@{0}

reset indext to cancel add operation and leave the file as it is

git reset HEAD xxxx.txt

ignore file permission change (chmod)

git config --local core.filemode false
git config --local --list

example of URIs

ssh://username@serverhostname/var/lib/git/myrepository.git
file:///var/lib/git/myrepository.git

ansible

エージェントレスの構成管理ツール。

対象ホストでは、エージェント等をインストールする必要がなく、基本的に下記を満たせばよい。

  • Pythonが動くこと
  • 相手がリモートホストならsshでログインできること

(ただし、使うモジュールによっては追加パッケージが必要。例:aptモジュールを使うためにはpython-aptが必要)

「あるべき姿」をYAMLで記載する。(記載したファイル(群)をplaybookと呼ぶ)

ansible
  -i hosts インベントリファイルを指定
  -m ping 疎通確認
  -m setup ファクト収集
  -a 'command -h' 指定したコマンドを実行
  --ask-pass ログインで必要となるパスワードを要求
  targethost 対象ホストを指定

リポジトリファイル(hosts)の内容の例

[myserver]
192.168.1.1 ansible_ssh_user=myusername
[desktop]
myhostname  ansible_connection=local

疎通確認の例

$ ansible -i hosts -m ping 192.168.1.1 --ask-pass
$ ansible -i hosts -m ping myhostname
    $ ansible -i hosts -m ping 192.168.1.1 --ask-pass --ssh-common-args '-o PubkeyAuthentication=no'

ansible-playbook
  -i hosts
  --syntax-check  プレイブックの文法チェックのみ
  --list-tasks   プレイブックのタスクをリスト表示
  --check ドライラン
  --ask-sudo-pass sudoで必要となるパスワードを要求
  --ask-su-pass suで必要となるパスワードを要求
  --ask-pass ログインで必要となるパスワードを要求
  --diff show differences
  --tags "tag1,tag2,..."
  --skip-tags "tag1,tag2,..."
  playbook.yml プレイブックを指定

プレイリストの内容確認、実行前確認、設定反映の例

$ ansible-playbook -i hosts --syntax-check myserver.yml
$ ansible-playbook -i hosts --list-tasks myserver.yml 
$ ansible-playbook -i hosts --check myserver.yml --ask-pass
$ ansible-playbook -i hosts myserver.yml --ask-pass

Sample ansible playbook in a single yaml file

resource monitoring

top

topコマンドを一回だけ実行して終了する(バッチモード)。

top -b -n 1

sar

sarで蓄積したデータの閲覧

LANG=C sar # LANGが日本語だと時分秒が日本語表記になるので、LANG=Cで実行
-q # loadaverage
-u # CPU
-b # I/O
-r # メモリ
-S # スワップ
:
:
-n DEV  # 送受信パケットの情報
   EDEV # エラーパケットの情報
   :
   :
-f /var/log/sa/saxx # 履歴ファイルを指定
-s hh:mm # 以降のデータを表示
-e hh:mm # 以前のデータを表示
(-fではなく、[interval] [count]の指定で、リアルタイム表示できるらしい)

network commands on linux

Recently, the iproute2 package's commands are recommended instead of net-tools to show or control network settings.

確認コマンド

show mac address table

ip [-6] neigh
arp -an

show interface mac address

ip link
ifconfig

show host ip address

ip [-6] addr
ifconfig

show routing table

ip [-6] route
netstat -rn
route -n

show tcp and udp port status

ss -an
netstat -an

query domain name server

dig <@nameserver> domainname [a|any|mx|ns|...]

cat << END > list.dig
@xxx.xxx.xxx.xxx example.com
@xxx.xxx.xxx.yyy example.com
END

dig -f list.dig


nslookup domainname <nameserver>

nslookup << exit
server xxx.xxx.xxx.xxx
example.org
example.com
exit

設定コマンド

down and up the link

ip link set br0 down
ip link set br0 up

delete and add from/to interface

ifconfig eth0 0.0.0.0
ifconfig eth0 192.168.0.1 netmask 255.255.255.0
ip address delete 192.168.0.1/24 dev enp0s25    
ip address add 192.168.0.1/24 brd + dev enp0s25

delete and add default gateway

ip route delete default
ip route add default via 192.168.0.254

add static route

ip route add 10.0.0.0/24 via 192.168.0.252

operate virtual bridge

show information of virtual bridge

brctl show
ip link show master br0
bridge link show

add and delete virtual bridge

ip link add br0 type bridge
ip link del br0
brctl addbr br0
brctl delbr br0

create tap0 and set pormiscuous mode

ip tuntap add dev tap0 mode tap
ip link set tap0 up promisc on
ip link set tap0 down promisc off
ip tuntap del dev tap0 mode tap

add and delete interface to virtual bridge

ip link set dev enp0s25 master br0
ip link set dev tap0 master br0
ip link set dev enp0s25 nomaster
brctl addif br0 eth0
brctl addif br0 tap0
brctl delif br0 eth0

write below to network config file and execute service networking restart

auto eth0
iface eth0 inet static
  address 0.0.0.0
auto br0
iface br0 inet static
  address 192.168.0.1
  netmask 255.255.255.0
  bridge_ports eth0

Alternatively you can use systemd-networkd for handling virtual bridge. At first put these 3 files in /etc/systemd/network

eth0.network

[Match]
Name=eth0

[Network]
Bridge=br0
## if you want to use this interface, comment out above line
## and specify dhcp or static address
#DHCP=ipv4
#Address=192.168.0.1
#Gateway=192.168.0.254
#DNS=192.168.0.254

br0.netdev

[NetDev]
Name=br0
Kind=bridge

br0.network

[Match]
Name=br0

[Network]
# DHCP=ipv4
Address=192.168.0.1
Gateway=192.168.0.254
DNS=192.168.0.254

then enable and start systemd-networkd

systemctl enable  systemd-networkd
systemctl restart systemd-networkd

openvswitch

show information of virtual bridge

ovs-vsctl show

add and delete virtual bridge

ovs-vsctl add-br br0
ovs-vsctl del-br br0

add and dlete interface to virtual bridge

ovs-vsctl add-port br0 eth0
ovs-vsctl add-port br0 tap0
ip link set br0 up
ovs-vsctl del-port br0 tap0
ovs-vsctl del-port br0 eth0

expect

自動ログインマクロというとTeratermマクロを思い浮かべがちだが、un*x の expect コマンドを使うこともできる。

マクロはホームディレクトリ等に保存してchmod 700 しておく。

expect を使ったssh自動ログインbashスクリプトの簡単な例(一部抜粋)

sshで自動ログインだけ考えたら、パスフレーズなしの秘密鍵を使えば済むが、マクロならその後の処理も自動化できる。

expect -c "
spawn ssh ${user}@${addr}
expect {
  \"s password: \" {
  send   \"${pass}\n\"
  }
}
interact
"

exit 0

expect をインタープリタとして使ったtelnet自動ログインスクリプトの簡単な例

#! /usr/bin/expect

set addr "hostname"
set user "username"
set pass "password"

spawn telnet ${addr}
expect {
  "login: "  {
  send "${user}\n"
  expect "Password: "
  send "${pass}\n"
  }
}
interact

archive and compress

compress

gzip

gzip filename
gunzip -lv filename.gz
gunzip filename.gz

gzip -c filename > filename.gz
gunzip -c filename.gz > filename

zless filename.gz

bzip2

bzip2 filename
bunzip2 filename.bz2

bzip2 -c filename > filename.bz2
bunzip2 -c filename.bz2 > filename

bzless filename.bz2

xz

xz filename
unxz filename.xz

xz -c filename > filename.xz
unxz -c filename.xz > filename

xzless filename.xz

Archive

tar

tar cf filename.tar filename.0
tar cf filename.tar dirname
tar tvf filename.tar
tar xv filename.tar [path/to/dir/targetfile]

zip

zip filename.zip filename
zip -r filename.zip dirname
unzip -lv filename.zip
unzip filename.zip [path/to/dir/targetfile]

7zip

7z a filename.7z filename
7z a -r filename.7z dirname
7z l filename.7z
7z x filename.7z [path/to/dir/targetfile]

tarとgzip

GNU版tarが使えない時のtar.gzファイルの圧縮

tar cf - file or dir ... | gzip -c > archive.tar.gz

同じく展開

gzip -cd archive.tar.gz | tar xf -

tar、gzipからbase64でエンコード。デコード・展開の確認

tar cf - file or dir ... | gzip -c | base64 - | base64 -i -d - | gzip -cd | tar tvf -
tar cf - file or dir ... | gzip -c | openssl enc -a | openssl enc -a -d | gzip -cd | tar tvf -

ログがローテートされてgzipで圧縮されると、いちいち展開して読むのがめんどくさい と思ってた。 以下のようなツールがあり、gzipで固められたテキストファイルをいちいち展開せずに処理することができる。超便利。

zcat zgrep zdiff zless

for bzip2

bzcat bzgrep bzdiff bzless

for xz

xzcat xzgrep xzdiff xzless

for zip

zipgrep

tar の圧縮オプション

  • Z: compress (Z)
  • z: gzip (gz)
  • j: bzip2 (bz2)
  • J: xz (xz)

zip

microsoft系osでもおなじみの形式

tarでアーカイブしてzip圧縮。展開の確認

tar cf - file or dir ... | zip - - | funzip | tar tvf -

無圧縮zipアーカイブ

zip -0r archive.zip dirname

暗号化

zip -e archive.zip filename

zipの標準的な暗号化方式は強度が弱い。また、アーカイブヘッダが暗号化されず、ファイル名等は隠匿できない。

  • 一定期間経てば保護する必要がなくなる内容を暗号化する用途であれば問題ない。
  • 見られても困らないファイル名になっているなら問題ない。

ならよいが、そうでなければ下記の対応が必要となる。

  • zipファイルを他のツール(gpg等)で暗号化する。
  • 他のアーカイブツール(7z等)を使う。

7z

zipよりも高い圧縮率をサポート。暗号化方式としてAES256をサポート。アーカイブヘッダの暗号化をサポート。 7zではファイルのuid/gidは保持しない。

(ubuntuのp7zipパッケージに含まれる7zrでは、暗号化できなかった。 p7zip-fullパッケージの7zを使うことで、暗号化することができた。)

7z形式で暗号化して圧縮(アーカイブヘッダも暗号化)。

7z a -t7z -p -mhe=on archive.7z dirname

lコマンドの-sltオプションで、暗号化されているか確認することができる。

7z l -slt archive.7z

ファイルの場合、悪意ある人の手に渡ったら、高性能の計算機で長時間パスワード解析されてしまう。 (キャッシュカードのPINコードのように、一定時間に一定回数失敗したら保護される、ということはない。) 内容が漏れたら困る暗号化ファイルには長いパスワードを使う。

圧縮音声など、さらなる圧縮を望まない場合、zipや7z等ではアーカイブのみで圧縮しないこともできる。

zip -0 ....
7z a -mx=0 ....

sed and awk

簡単な使い方の例を記載する。

sed

2行目以降で、fooをbarに全て置換

sed -e '2,$ s/foo/bar/g' filename

20行目の次に「(タブ)added text」を追加、10行目を削除

sed -e '20i\\tadded text' -e '10d' filename

exprを含まない行だけ表示

sed -ne '/expr/! p' filename

後方参照

df /tmp | grep ^/ | awk '{print $5}' | sed -e 's/\([0-9]\{1,2\}\)%/\1/'

df /tmp | sed -ne 's/.* \([0-9]\{1,2\}\)% .*/\1/ p'

replace CR + LF to LF

sed  -e  's/\r$//' -i.bak textfile
perl -pe 's/\r$//' -i.bak textfile

replace LF to CR + LF

sed  -e  's/$/\r/' -i.bak textfile
perl -pe 's/$/\r/' -i.bak textfile

連続した空白文字をタブに置換

sed  -e   's/\s\s*/\t/g' test
perl -ple 's/\s+/,/g'    test

置換先文字列としてシェル変数を使う。

sed  -e 's/^/'"${foo}"'/' test

削除、挿入、置換を実行するsedスクリプトの例

#! /bin/sed -f

3,5d
8i \
# inserted comment\
inserted line # this is inserted
20 s/^/#/

awk

2行目から3行目までを表示

awk '(NR>=2 && NR<=3) {print $0}' filename

行番号を表示

awk '{printf "%02d: %s\n", NR, $0}' filename

IPv4アドレスの第1オクテットが192のものの第2オクテットを抜き出す

awk -F. '$1~/192/ {print $2}' filename
perl -F"\." -alne '{print $F[1]}' filename

コマンドにシェル変数を使う。

awk '{print '"${foo}"', $1}' test
(fooが2017-08のような文字列だと、数値として扱われて演算結果が表示される)

awk -v var=${foo} '{print var, $1}' test
(こちらの例では、そのようなことはない)

スクリプトファイルにコマンドを記載して実行

awk -f script.awk textfile

下記の場合、shebangとして、#! /path/to/awk -f などと記載

chmod u+x script.awk
./script.awk textfile

行頭に2桁の行番号をつけて出力するawkスクリプト

#! /bin/awk -f

BEGIN{
  print "script begin"
}
{
  printf "%02d: %s\n", NR,$0
}
END {
  print "script end"
}