2018年12月6日木曜日

シェル 引用符で囲まれた文字列内の空白について

2018 Dec. 06.

bash上で 'ls -l'という文字列を格納した変数とディレクトリを格納した変数をスペースで区切って次のようにシェルに入力すると"ls -l: コマンドが見つかりません"となる。
一方、変数を引用符で囲ますにシェルに与えると"ls -l"の結果が出力される。
シェルにおける空白の解釈
・クォートで囲まれた文字列内の空白は単なる文字(変数文字列のトークンの一部)
・シェルにとって、引用符に囲まれていない空白は文字ではなく区切り記号

$ 'ls -l' '/'
ls -l: コマンドが見つかりません

$ "ls -l" "/"
ls -l: コマンドが見つかりません

$ s1='ls -l'
$ s2='/'
$ "$s1" "$s2"
ls -l: コマンドが見つかりません

$ s1='ls -l'
$ s2='/'
$ $s1 $s2
(ls -lの結果が出力される)

2018年12月1日土曜日

カーネルモジュールが置かれる場所

2018 Dec. 01.

カーネルモジュールは
 /lib/modules/`uname -r`/kernel/
に置かれる。

例)pt2ドライバー
/lib/modules/`uname -r`/kernel/drivers/video/pt1_drv.ko

2018年11月4日日曜日

git リモートとローカルのブランチ比較

2018 Nov. 04.

こちらを参照


git pull する前にリモートとの変更点を見る

$ git diff HEAD..リモート名/ブランチ名

git push する前にリモートとの変更点を見る

$ git diff リモート名/ブランチ名..HEAD

git add する前に変更点を見る

$ git diff

git add した後に変更点を見る

$ git diff --cached

 今回コミットした変更点を見る

$ git diff HEAD^

2018年10月28日日曜日

カーネルアップデート時のドライバーモジュールアップデートの自動化

2018 Dec. 31.
2018 Dec. 23.
2018 Nov. 14.
2018 Oct. 28.

【TVチューナー PT2 の例】

dkmsパッケージインストール

# apt update && apt install dkms

ソースファイル配置

$ cd PT2/DRIVER/SOURCE/driver/
$ make clean
$ sudo cp -r ./* /usr/src/pt1-17b4f7b5dccb/

dkms設定

/usr/src/pt1-17b4f7b5dccb/dkms.conf を次の内容で作成する。
PACKAGE_NAME="pt1"
PACKAGE_VERSION="17b4f7b5dccb"
CLEAN="make clean"
MAKE="make"
BUILT_MODULE_NAME="pt1_drv"
DEST_MODULE_LOCATION="/kernel/drivers/video/"
AUTOINSTALL="YES"
 

ドライバーインストール

"# make install"でインストールされたファイルを削除する。
  PT2/DRIVER/SOURCE/driver/Makefileに記述された "install: $(TARGET)"セクションの
  install -m 644 $(TARGET) /lib/modules/`uname -r`/kernel/drivers/video
  でインストールされた
  /lib/modules/`uname -r`/kernel/drivers/video/pt1_drv.ko
  を削除する。
 
# dkms install -m pt1 -v 17b4f7b5dccb 
 

インストール確認

# dkms status | grep pt1
pt1, 17b4f7b5dccb, 4.15.0-38-generic, x86_64: installed

ドライバーファイルの配置場所
 /lib/modules/`uname -r`/updates/dkms/pt1_drv.ko 
 

ドライバ読み込み確認

$ lsmod | grep pt1_drv
$ ls -l /dev/pt1*

ドライバ読み込み

# modprobe pt1_drv
 

アンインストール

# dkms uninstall -m pt1 -v 17b4f7b5dccb
 

ソースパッケージの登録削除

# dkms remove -m pt1 -v 17b4f7b5dccb --all

2018年10月26日金曜日

"ls -l"出力からファイルサイズ列を取り出す

2018 Oct. 26.


$ ls -l | awk 'NR > 1 ' | sed -e "s/[ $'\t'][ $'\t']*/ /g" | cut -d " " -f 5

  [ $'\t'] : スペースもしくはタブ($'\t')

2018年10月21日日曜日

mysql select結果をcsvファイルに書き出す

2018 Oct. 21.


csvファイル書き出し

ユーザにfile権限を付与する

        $ mysql -u root -p DATABASE

        mysql> grant file on *.* to 'USER'@'localhost' ;

当該ユーザー でmysqlに接続してファイル出力する

$ mysql -u USER -p DATABASE

(カンマ区切り、二重引用符囲みで/var/lib/mysql-files/ディレクトリに出力)
    --secure-file-priv が設定された状態であれば
     SELECT @@secure_file_priv; を実行し
     出力表示されたディレクトリにCSVファイルを保存するようにする。

mysql> select * from TABLE WHERE CONDITION INTO OUTFILE "/var/lib/mysql-files/TEXTFILENAME" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n";

(列名を先頭行につけて出力)
mysql> select 'col1','col2', ... union select * from TABLE WHERE CONDITION INTO OUTFILE "/var/lib/mysql-files/TEXTFILENAME" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n";
     
書き込み先はmysqlユーザが書き込み権限のあるディレクトリでないと
いけない。
    /tmpディレクトリが無難。
    書込先ファイルの上書きはできない。ので、同名ファイルは削除しておく。

Output csv-file for standard-output.(二重引用符囲み無し。カンマ区切り)
$ mysql -u USER --password='PASSWORD' -e "SELECT *  from TABLE" DATABASE | sed -e 's/\t/,/g' > outfile.csv

(sample)
$ mysql --user epgrec --password='PASSWORD' -e 'SELECT path,starttime,title,description,type,channel from Recorder_reserveTbl where complete = 1 and dirty = 0 order by starttime desc' epgrec | sed -e 's/\t/,/g' > ~/video_list.csv


  sql結果のファイル出力

  $ mysql --user epgrec --password='epgrec106' epgrec > OUTFILE
  SQL文の入力待ちになったところで
  select path from Recorder_reserveTbl order by path asc ;
  \q
  と入力するとファイルが作成される。

2018年10月20日土曜日

mysql ファイル書き込みディレクトリ制約の解除

2018 Oct. 20.

https://qiita.com/bohebohechan/items/207e87786b1e30f60abe より

概要

secure-file-priv に設定されたディレクトリのみに書き込みができる。
secure-file-privの設定がNULLであれば書き込み制約されない。
書き込み属性が、mysqlユーザーを許可するディレクトリであること。

secure-file-privの確認

mysql> SELECT @@global.secure_file_priv;
 

secure-file-privの設定

/etc/mysql/conf.d/my.cnfを編集し、mysqlサーバーを再起動する。

(/etc/my.cnfでのNULL設定)
 [mysqld]
secure-file-priv = ""
 
 
 

git リモートのbranchの確認、ローカルブランチとの確認

2018 Nov. 11.
2018 Oct. 20.

リモートのbranchの確認

次の2つのコマンドを実行する
$ git fetch
$ git branch -a

リモートブランチとローカルブランチの比較

$ git diff master origin/master
 

2018年10月14日日曜日

cron 起動するスクリプト・プログラムのライブラリパスを設定すること

2018 Oct. 14.

cronの@rebootで起動させるruby/sinatraが、RUBYLIB設定が無いので起動しないことに気づくまで随分時間を使ってしまった。

2018年10月8日月曜日

mysql パスワードポリシー変更/無効化

2019 Oct. 21.
2018 Oct. 21.
2018 Oct. 08.

永続的変更(こちらで運用中)

mysqlサーバー設定ファイル *.cnf を編集する[mysqld] validate_password_policy=LOW  上記を設定するとmysqlサーバーの起動に失敗するので、下記とした。 rootでmysqlに接続し、下記コマンドでvalidate_passwordプラグインを削除し、mysqlサーバーを再起動する mysql> uninstall plugin validate_password;

一時的変更(mysqlサーバーを再起動すると設定が消える)

 $ mysql -p -u root

(設定確認) 
mysql> SHOW VARIABLES LIKE 'validate_password%';

(ポリシー変更) 
 mysql> set global validate_password_policy=LOW;
 

2018年10月7日日曜日

OpenVPNインストール ルーティング方式 Easy-RSA3利用、TLS認証あり版

2019 Oct. 21.
2019 Apr. 27.
2018 Oct. 08.
2018 Oct. 07.
2018 Sep. 27.
2018 Sep. 02.

インストール

こちら(https://qiita.com/noraworld/items/2fe6be489e1d93c748b8) を参照

 

 プログラムインストール

# apt install openvpn
$ cd ~/YOUR-WORK-DIR
$ git clone https://github.com/OpenVPN/easy-rsa.git
 

初期設定

$ cd ~/YOUR-WORK-DIR/easy-rsa/easyrsa3
$ ./easyrsa init-pki

 

 CA証明書生成

以後入力するパスフレーズはすべて同じにしておいた方が楽。
CA名称は "ホスト名+OS名" にした。 
$ ./easyrsa build-ca
$ sudo cp pki/ca.crt /etc/openvpn/

 

サーバ証明書生成

$ ./easyrsa build-server-full server nopass
$ sudo cp pki/issued/server.crt /etc/openvpn/
$ sudo cp pki/private/server.key /etc/openvpn/

 

DH鍵生成

$ ./easyrsa gen-dh
$ sudo cp pki/dh.pem /etc/openvpn/
 

TLS鍵生成

$ openvpn --genkey --secret ./pki/ta.key
$ sudo cp ./pki/ta.key /etc/openvpn/
 

クライアント証明書生成

$ ./easyrsa gen-crl
$ sudo cp pki/crl.pem /etc/openvpn/
$ sudo chmod o+r /etc/openvpn/crl.pem

 

サーバー設定ファイル記述

# touch /etc/openvpn/server.conf
 
/etc/openvpn/server.confを編集
###########
port   1194
proto  udp
dev    tun
 
cipher AES-256-CBC
auth SHA512 
 
ca          ca.crt
cert        server.crt
key         server.key
dh          dh.pem
crl-verify  crl.pem 
 
tls-auth ta.key 0 
 
ifconfig-pool-persist ipp.txt

server 10.8.0.0 255.255.255.0

push "redirect-gateway def1 bypass-dhcp"
push "route 10.8.0.0 255.255.255.0"
push "dhcp-option DNS 8.8.8.8"

client-to-client
keepalive 10 120
comp-lzo

user  nobody
group nogroup

persist-key
persist-tun

status      /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

verb 3 
###########

 

ファイアウォール設定

# ufw enable 
# ufw allow 1194/udp
# ufw reload
 

IPフォワーディング設定

 /etc/default/ufw を編集する
  DEFAULT_FORWARD_POLICYをDROPからACCEPTに変更する
    - DEFAULT_FORWARD_POLICY="DROP"
    + DEFAULT_FORWARD_POLICY="ACCEPT"
 
 IPフォワーディングを有効化
  /etc/ufw/sysctl.confを編集する
   net.ipv4.ip_forward=1の一行をアンコメントする
    - # net.ipv4.ip_forward=1
    + net.ipv4.ip_forward=1
 

IPマスカレード有効化

 ifconfigでネットワークポート名を確認する( enp0s7 とか)
 /etc/ufw/before.rulesを編集する
  一番下の行にCOMMITと書かれているはずなので、この下に以下を追加する。
  ( *nat行の上のCOMMITは削除しない)
 
   COMMIT
   +
   + *nat
   + :POSTROUTING ACCEPT [0:0]
   + -A POSTROUTING -s 10.8.0.0/24 -o enp0s7 -j MASQUERADE
   + COMMIT
 
 # ufw reload
 

Logローテーション設定

こちら(https://gtrt7.com/blog/linux/ubuntu-openvpn) を参照
OpenVPNログローテーション設定ファイル新規作成
/etc/logrotate.d/openvpn を編集する。
/var/log/openvpn-status.log {
weekly
rotate 7
delaycompress
compress
missingok
notifempty
}
/var/log/openvpn.log {
weekly
rotate 7
delaycompress
compress  missingok
notifempty
sharedscripts
postrotate
systemctl restart openvpn@server 2>&1 > /dev/null || true
endscript
}

OpenVPN起動

# systemctl start openvpn@server.service

起動確認
$ ps ax -f | grep openvpn | grep -v grep
 
$ systemctl status openvpn@server.service
   Active: active (running) の表示を確認する
 

OpenVPN自動起動設定

# systemctl disable openvpn
# systemctl disable openvpn.service

# systemctl enable openvpn@server.service

確認 
$ systemctl is-enabled openvpn openvpn.service openvpn@server.service
 

クライアント用秘密鍵の生成

$ cd ~/YOUR-WORK-DIR/easy-rsa/easyrsa3 
 
(接続時パスワード無し) $ ./easyrsa build-client-full HOGE nopass
(接続時パスワード有り) $ ./easyrsa build-client-full HOGE

(HOGEは "サーバー名+サーバーOS+クライアント端末名" とした)

 

$ mkdir ~/CLIENT-FILE-DIR
$ sudo cp /etc/openvpn/ca.crt ~/CLIENT-FILE-DIR/
$ cp pki/issued/HOGE.crt ~/CLIENT-FILE-DIR/
$ cp pki/private/HOGE.key ~/CLIENT-FILE-DIR/
$ sudo chown USER:USER ~/CLIENT-FILE-DIR/ca.crt
$ chown USER:USER ~/CLIENT-FILE-DIR/HOGE.crt
$ chown USER:USER ~/CLIENT-FILE-DIR/HOGE.key
  USER: VPNサーバに現在ログインしているユーザのユーザ名 
 

接続するクライアントに鍵ファイルをダウンロード

$ scp ~/CLIENT-FILE-DIR/ca.crt CLIENT
$ scp ~/CLIENT-FILE-DIR/HOGE.crt CLIENT
$ scp ~/CLIENT-FILE-DIR/HOGE.key CLIENT
$ scp ./pki/ta.key CLIENT
  

VPN.ovpn を作る(ファイル名は任意だが、拡張子は .ovpn )

client
dev    tun
proto  udp
remote YOUR.GLOBAL.ADDRESS.HERE 1194
resolv-retry  infinite
nobind
tls-auth ta.key 1
persist-key
persist-tun
cipher AES-256-CBC
auth SHA512
ca    ca.crt
cert  CLIENTDEVNAME.crt
key   CLIENTDEVNAME.key
comp-lzo
verb 3

# persist-key, persist-tun, comp-lzo, verb はサーバ側と同じにする。サーバ側に設定してあればこちらにも入力し、設定していない場合は外す。

VPN.ovpn をクライアントにコピー

  $ scp VPN.ovpn CLIENT


android端末にOpenVPN for Androidをインストールする

OpenVPN for Androidを開き、「プロファイルの追加」アイコンをタップして、 .ovpnファイルをインポートし、他の3ファイルを読み込む。

OpenVPN for Android 設定

種別: 証明書
CA証明書 ca.crt
クライアント証明書  CLIENTDEVNAME.crt
クライアント証明書のキー CLIENTDEVNAME.key
ポート番号 1194
プロコトル UDP

TLS認証を使用する :  on
暗号化方式: AES-256-CBC



設定

WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this

This is nothing to worry about.
https://support.hidemyass.com/hc/en-us/articles/202720436-Auth-nocache-Warning-in-OpenVPN-connection-log


WARNING: cipher   local='cipher BF-CBC'  remote='cipher AES-256-CBC'

クライアントの暗号化方式を AES-256-CBS に指定する。
参考サイト

WARNING: No server certificate verification method has been enabled. 

クライアント設定で「TLSサーバー証明書を要求する」をオンにする。


VPN経由でアクセスするLAN内の各種サーバーの設定

http://rokkonet.blogspot.com/2018/05/openvpn.html


2018年10月3日水曜日

OpenVPN クライアントからサーバーに接続時のパスワード要否設定

2018 Oct. 07.
2018 Oct. 03.

クライアント秘密鍵の生成で
$ ./easyrsa build-client-full 設定ファイル名 nopass
とコマンドの最後にnopassオプションを指定すればパスフレーズが不要となる

2018年10月1日月曜日

TS-MPEG2ファイルをDVD-VIDEOに焼く

2018 Oct. 01.

TS-MPEG2ファイルをDVD-VIDEO用MPEG2ファイルに変換する

こちら を参照

DVD-VIDEO用MPEG2ファイルをDVD-VIDEO形式にオーサリングする

$ VIDEO_FORMAT=NTSC dvdauthor -t -o OutDir InFile.mpg

ビデオマネージャ (VMG) を作成する

$ VIDEO_FORMAT=NTSC dvdauthor -T -o OutDir

ディスクイメージを作成する

$ genisoimage -dvd-video -udf -V LABEL -o Dvd.iso OutDir

DVD-Rに焼き付ける 

Brasero でDvd.isoをDVD-Rに焼く

TS-MPEG2ファイルをDVD-VIDEO用MPEG2ファイルに変換する

2018 Oct. 1.

$ ffmpeg -i InFile.ts -target ntsc-dvd OutFile.mpg

2018年9月28日金曜日

Sophos Anti-Virus for Linux インストール

2019 Jan. 04.
2018 Sep. 29.
2018 Sep. 28.

オンアクセス検索とオンデマンド検索が可能

インストール

http://zokibayashi.hatenablog.com/entry/2015/05/27/233114
https://qiita.com/ayuri/items/342a0ddbd861ab1f5134

オンデマンド検索

PC全体をスキャン

# savscan /
  インストール時に全体スキャンを行っておく。

特定のディレクトリを検索しない
# savscan / -exclude /sys /proc /dev

検知ウイルスファイルを削除

# savscan /DIR -remove

検知ウイルスファイルを隔離

# savscan /DIR --quarantine : 隔離する


圧縮ファイル内も検索

# savscan /DIR -archive


オンアクセス検索

初期設定は検索だけで隔離・削除はされない

環境設定ガイドには「オンアクセス検索のオプションに「メールボックス全体が削除されることがあるので、感染ファイル削除を有効にしないように」と書かれている。

感染ファイル対応

検索のログ内容をユーザーに知らせるなどして、ユーザーに対応を促す。

(/var/log/syslog)

オンアクセス検索
Sep 29 07:49:10 pc savd: savscan.log: On-demand scan started.
Sep 29 07:49:27 pc savd: savscan.log: On-demand scan details: master boot records scanned: 0, boot records scanned: 0, files scanned: 6, scan errors: 0, threats detected: 1, infected files detected: 1
Sep 29 07:49:27 pc savd: Threat detected in /home/user/eicar.com: EICAR-AV-Test during on-demand scan. (The file is still infected.)
Sep 29 07:49:28 pc savd: savscan.log: On-demand scan finished.

オンデマンド検索
Sep 29 07:52:04 pc savd: Threat detected: EICAR-AV-Test in /home/user/eicar.com

ドキュメント

https://www.sophos.com/ja-jp/support/documentation/sophos-anti-virus-for-linux.aspx
https://www.sophos.com/ja-jp/medialibrary/PDFs/documentation/savl_9_sgeng.pdf
https://www.sophos.com/ja-jp/medialibrary/PDFs/documentation/savl_9_cgeng.pdf

2018年9月23日日曜日

インターネット回線速度計測

2018 Sep. 23.

# apt install speedtest-cli

メール送信システム ( postfix, mail ) インストールとgmailリレー送信設定

2018 Sep. 23.

こちらのページは無視してよい。

( https://blog.ymyzk.com/2017/06/postfix-smarthost-gmail/ より)

gmailアカウント

2段階認証プロセス:オフ
安全性の低いアプリの許可:有効

パッケージインストール


# apt install postfix bsd-mailx libsasl2-modules
  postfix設定問い合わせでは、Internet with smarthost を選択し、
  ”SMTP relay host” には [smtp.gmail.com]:587 を記述する

設定

/etc/postfix/sasl_passwd を次の1行の内容で作成する

[smtp.gmail.com]:587 gmailアカウント@gmail.com:パスワード
: をアカウントとパスワードで挟んだ書式)

# cd /etc/postfix
# chmod 600 sasl_passwd
# postmap /etc/postfix/sasl_passwd
 
/etc/postfix/main.cf に次の4行を追記する

smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
 

postfix再起動

# systemctl restart postfix.service
 

メール送信

$ Msg="読めますか?\n2行目です。\n3行目です"
$ Title='メール試験'
$ MailDest="hoo@example.xx bar@example.yy"
$ echo -e "${Msg}" | mail -s `echo -e "${Title}" | nkf -jM` $MailDest
 
(下記のように本文をjisコードにすると文字化けした) 
$ echo -e "${Msg}" | nkf -j  | mail -s `echo -e "${Title}" | nkf -jM` $MailDest


確認

# tail -f /var/log/mail.log

crontab 編集エディタ設定

2018 Sep. 23.

$ EDITOR=vim
$ export EDITOR

2018年9月15日土曜日

ruby rbenv, bundlerでのアプリケーション実行

2018 Oct. 08.
2018 Sep. 15.

$ CmdPath=`find / -name 'RUBY.rb' -exec dirname {} \;`
$ pushd $CmdPath
$ rbenv exec bundle exec RUBY.rb
$ popd


cronで利用するときは、PATH, RUBYLIBの設定をcronに記載することを忘れないように

ruby 各プロジェクトでのbundler設定

2018 Sep. 15.

$ cd projectーdir
$ rbenv exec bundle init

$ vi Gemfile
  gem "sinatra"
  gem "pry"
  gem "mysql2"
  gem "OptionParser"
  gem "systemu"

$ rbenv exec bundle install --path vendor/bundle

複数のrubyプログラム間での調整

2018 Sep. 15.

dir-a/a.rb  <= 主たる実行ファイル
    require "b.rb"

dir-b/Gemfile
    gem "gem-a"

dir-b/b.rb  <= a.rbがrequireするファイル
    require "bundler"
    Bundler.require  <= require "gem-a" が行われる
 
  dir-a/Gemfile に gem-a を書き込んでgemをインストールし、
  dir-a/をカレントディレクトリとして起動すれば、
  実行できる。
  dir-b/ のGemfileにgem-aを書き込んでいるだけではloadエラーとなる。

  シェルスクリプト内での記載例
    SRCPATH=$(readlink -f `which RUBY.rb`)
    pushd $(dirname ${SRCPATH})
    rbenv exec bundle exec $SRCPATH
    popd

ruby gemファイルのrequire書式

2018 Sep. 15.


rubyスクリプトでの gemファイルのrequire の書き方

( http://shokai.org/blog/archives/7262 より)
プログラム内で
require 'bundler'
Bundler.require
と書くと、gemが一括requireできる。

rubyスクリプト renv環境でのシバン(先頭行)


2018 Sep. 15.




rbenv環境でのrubyスクリプトの1行目の書式

#!/usr/bin/env ruby

mysql ユーザー一覧

2018 Sep. 15.

mysql> select Host, User from mysql.user;

RTMPサーバー設置

2019 Jan. 04.
2018 Sep. 15.

nginxサーバーのrtmpモジュールをインストールし、/etc/nginx/nginx.conf を編集する。

rtmpモジュールパッケージインストール

# apt install libnginx-mod-rtmp



設定

( http://technical.live-on.net/archives/1423 より)

メディア配置ディレクトリ

任意のメディア配置ディレクトリに、 mp4またはflvファイルを配置する。
 例)/usr/local/nginx/mp4s;
   /usr/local/nginx/flvs;



/etc/nginx/nginx.conf 編集

## ここから ##
rtmp {
    server {
        listen 1935;

        # video on demand for flv files
        application vod {
           # live off; を入れる事で、rtmp://で直接ストリームが送られてくることを防ぐことができます。

            live off;
            play /usr/local/nginx/flvs;
        }

        # video on demand for mp4 files
        application vod2 {
            live off;
            play /usr/local/nginx/mp4s;
        }
    }
}

# 以下の http { } は書かなくても、以前からの設定で動いた。
# HTTP can be used for accessing RTMP stats
http {
    access_log /usr/local/nginx/logs/access-streaming.log;
    error_log /usr/local/nginx/logs/error-streaming.log;

    server {
        # in case we have another web server on port 80
        listen      80;

        location / {
            root   html;
            index  index.html index.htm;
        }

    }
}
## ここまで ##


1935ポート開放

# ufw allow proto tcp from 192.168.1.0/255.255.255.0 to any port 1935
# ufw allow proto udp from 192.168.1.0/255.255.255.0 to any port 1935
# ufw allow proto tcp from 10.8.0.0/24 to any port 1935
# ufw allow proto udp from 10.8.0.0/24 to any port 1935
# ufw reload

視聴

VLC Plyerで再生できるかを確認
  ネットワークストリームを開く
  rtmp://IPアドレス/vod2/MEDIA.mp4


  視聴できたが、早送り・巻き戻しができなかった


webプレーヤーで再生できるか確認
 <html>
<head>
   <link href="http://vjs.zencdn.net/5.11.6/video-js.css" rel="stylesheet">
   <script src="http://vjs.zencdn.net/5.11.6/video.js"></script>
</head>
<body>
   <video id="rtmp_test" class="video-js vjs-default-skin" autoplay="autoplay" controls="controls" width="800" height="450" data-setup="{}">
   <source src="rtmp:// IPアドレス/vod2/MEDIA.mp4" type="rtmp/mp4" />
</video>
</body>
</html>



以下、未実践

NGINX の configuration 設定

( https://ygoto3.com/posts/live-streaming-and-rtmp-for-frontend-engineers/ より)

rtmp://localhost:1935/live という URL で RTMP サーバに接続が可能にする

 (nginx.conf)
user nginx;
worker_processes 1;
daemon off;
events {
  ...
}

http {
  ...
}

rtmp {
    server {
        listen 1935;
        listen [::]:1935 ipv6only=on;

        application live {
            live on;
            record off;
        }
    }
}





HLS m3u8 サーバー設定

https://qiita.com/yo_dazy/items/e14464367ec8d4a26b6a より

画像ファイルの格納ディレクトリ作成とConfig設定

# mkdir /usr/local/nginx/html/movie
# chown nobody /usr/local/nginx/html/movie

 /usr/local/nginx/conf/nginx.conf 編集

rtmp {
    server {
        # Rtmp Port
        listen 1935;
        access_log logs/rtmp_access.log;
        application livet {
            live on;
            wait_video on;
            # IP を絞る場合以下の設定を有効化
            # allow publish 192.168.1.0/24;
            # deny publixh all;
            hls on;
            hls_path /usr/local/nginx/html/test2;
            hls_fragment 5s;
        }
        ####VOD In Add ########
        application vod {
           play /usr/local/nginx/html/movie; // 動画を格納するディレクトリを指定する
        #######################
        }
    }
}


nginx 起動確認
作業端末(インターネットに接続できる環境)より以下に接続
http://<「ストリーミングサーバ」のPublicIP>

 スマホで撮った動画をサーバに格納してファイル形式をMP4からm3u8に変換します。
 格納先は【5.[nginx.config]編集】で作成した動画格納ディレクトリになります
 格納した動画ファイルをHLSに変換します。

 # HLS 変換コマンド
#<動画ファイル2> :格納した動画ファイルから拡張子を抜いてください
ffmpeg -re -i 180320_100150.mp4<動画ファイル> -vcodec libx264 -vprofile baseline -acodec copy -ar 44100 -ac 1 -f segment -segment_format mpegts -segment_time 10 -segment_list 180320_100150<動画ファイル2>.m3u8 180320_100150<動画ファイル2>-%03d.ts

 コマンド実行前と実行後

#実行前
[root@WHSMINI movie]# ls /usr/local/nginx/html/movie
180320_100150.mp4
#実行後
[root@WHSMINI movie]# ls /usr/local/nginx/html/movie
180320_100150-000.ts  180320_100150-001.ts  180320_100150-002.ts  180320_100150.m3u8  180320_100150.mp4


[html]ファイル編集
WEB動画を配信させるページへのリンクページです。index.htmlを書き換えます。

# rm -rf /usr/local/nginx/html/index.html
# vi /usr/local/nginx/html/index.html


 index.html

<DOCTYPE html>
<html lang="en" class="">
<body>
<p>This Is Web Storeaming StartPage!!</p>
<hr>
<a href="vod.html">Video On Demand</a>
</body>


 [Video On Demand]ページの作成
vi /usr/local/nginx/html/vod.html

 vod.html

<DOCTYPE html>
<html lang="en" class="">
<head>
    <title>ONDEMAND</title>
    <link href="//vjs.zencdn.net/5.11/video-js.min.css" rel="stylesheet">
    <script src="//cdn.jsdelivr.net/hls.js/latest/hls.min.js"></script>

</head>
<body>
<p> Video On Demand </p>
<video id="video" class="video-js vjs-default-skin" width="640" height="480" controls>
<script type="text/javascript">
    // 変換した動画ファイルを指定します。
    var source = '/movie/180320_100150.m3u8';
    var ua = navigator.userAgent;
  // スマホからのアクセスか、それ以外のアクセスかを判断
    if (ua.indexOf('iPhone') > 0 || ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0) {
        // iOS
        document.write('<source src=' + source + ' type="application/x-mpegURL">');
        document.write('</video>');

    }else{
        // OTHER
        document.write('</video>');
        if(Hls.isSupported()) {
            var video = document.getElementById('video');
            var hls = new Hls();
            hls.loadSource(source);
            hls.attachMedia(video);
            hls.on(Hls.Events.MANIFEST_PARSED,function() {
                video.pause();
            });
        }
    }
</script>
</body>
</html>


2018年9月13日木曜日

ubuntu + nginx + mysql + php インストール

2018 Sep. 15.
2018 Sep. 13.


https://beautifulajax.dip.jp/?p=1825 より

関連ソフトインストール

# apt install nginx mysql-server
# systemctl start nginx
# apt install php php-fpm php-mysql php-gettext php-common php-mbstring php-mbstring

php設定

/etc/php/7.2/fpm/php.ini を編集する

  cgi.fix_pathinfo=0

/etc/php/7.2/fpm/pool.d/www.conf を編集する
  php_admin_value[memory_limit] = 128M

# service php7.2-fpm restart

nginx設定

 /etc/nginx/sites-available/default を編集する
  server {
  }
  の中に、下記を書き込む。

   # ディレクトリ内のファイル一覧を表示する場合
   autoindex on;

   location ~ \.php$ {
          try_files $uri =404;
          fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
   }



confファイルを編集する
 fastcgi_param PHP_VALUE "memory_limit = 128M";

 次の1行の内容の/var/www/html/phpinfo.phpファイルを作成する
  <?php phpinfo(); ?>


nginx起動

# systemctl restart nginx

http://NGINX-SERVER/xxx
"xxx" にでたらめな文字列を入れてhttp://NGINX-SERVERにアクセスし、nginxから404 Not Foundが送られてくることを確認する


404 Not Found


nginx/1.14.0 (Ubuntu)


http://NGINX-SERVER/phpinfo.php にアクセスしてphpinfo画面が表示されることを確認する 


mysqlインストール

http://rokkonet.blogspot.com/2018/09/mysql.html 




2018年9月9日日曜日

mysql ユーザー@ホストの確認

2018 Oct. 21.
2018 Sep. 09.

mysql> user mysql
mysql> select  host,user from mysql.user;

2018年9月2日日曜日

mysqlインストール

2019 Nov. 02.
2019 Oct. 14.
2019 Jan. 03.
2019 Jan. 02.
2018 Nov. 18.
2018 Sep. 15.
2018 Sep. 02.

インストール

# apt install mysql-server
続いて
# mysql_secure_installation
  質問にはすべて "y" でよい。

"$ mysql -p -u root" でログインできるようにする


"$ mysql -p -u root" でログインできない状態となっている。
"$ sudo mysql -p -u root" ならログインできる。
  
"$ mysql -p -u root" でログインできるようにする
( https://note.mu/junf/n/na40fbca9e6ea )
 
  $ sudo mysql -u root -p
  mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'PASSWORD';
  mysql> FLUSH PRIVILEGES; 
  別のターミナルを開いて sudo 無しでログインできるか確認する


利用文字コードをutf8にする。

/etc/mysql/conf.d/ に拡張子を".cnf"とする任意なファイル名で次の設定を記述

あるいは

 ~/.my.cnf に記述


  [client]
  # default-character-set = utf8 (設定すると日本語入力できない)

  [mysqld]
  character-set-server=utf8
    # default-character-set = utf8 ではmysqlが起動しない

  [mysqldump]
  default-character-set = utf8

  [mysql]
  # default-character-set = utf8 (設定すると日本語入力できない)

 

  確認

( www.jifu-labo.net/2015/09/ubuntu_epgrecuna/ より)
$ mysql -u root -p
   文字コードの設定に問題がないか確認。
   set_filesystemとsets_dir以外が全てutf8ならば問題ない。
  mysql> show variables like "char%";
  +--------------------------+----------------------------+
  | Variable_name            | Value                      |
  +--------------------------+----------------------------+
  | character_set_client     | utf8                       |
  | character_set_connection | utf8                       |
  | character_set_database   | utf8                       |
  | character_set_filesystem | binary                     |
  | character_set_results    | utf8                       |
  | character_set_server     | utf8                       |
  | character_set_system     | utf8                       |
  | character_sets_dir       | /usr/share/mysql/charsets/ |
  +--------------------------+----------------------------+
  8 rows in set (0.01 sec)


 EPGREC用設定

sql-modeの指定をしない(strict制約をしない)。sql_mode=''
・書き出し先ディレクトリ制約をしない。secure-file-priv = ""

[mysqld]
sql_mode=''
secure-file-priv = ""



ネットワーク(127.0.0.1 を含む)からのアクセスを許可する

/etc/mysql/ 内の設定ファイルに
skip-networking
の行があれば削除もしくはコメント化する。

外部からのにアクセスを許可する場合

アクセス許可するIPアドレス設定(bind-address = 0.0.0.0)

/etc/mysql.conf.d/mysqld.cnf の "bind-address = xxx.xxx.xxx.xxx" を修正する。
 すべてのIPアドレスからのアスセスを許可 ->  bind-address = 0.0.0.0
 localhostからのアクセスのみを許可 -> bind-address =127.0.0.1
 bind-addressを複数行記述すると最終行のみが有効。
 1行に、スペース区切りで複数アドレスを記述すると最初のアドレスのみが有効。
 "xxx.xxx.xxx." "xxx.xxx.xxx.0/24" "xxx.xxx.xxx.0/255.255.255.0" といった記述はできない。


/etc/hosts.allow 設定


  mysqld: ALL  (すべてのIPアドレスからのアクセスを許可)
  mysqld: 127.0.0.1  (localhostからのアクセスを許可)
  mysqld: 192.168.1.  (192.168.1/24からのアクセスを許可)

3306ポート開放

# ufw enable
# ufw allow 3306/tcp
# ufw allow 3306/udp

3306ポートをLISTENしているのを確認する。
$ netstat -na | grep 3306
$ mysql -h 127.0.0.1 -P 3306 -u root -p
 

PC shutdown時にmysqlが終了しない現象を防ぐ(ubuntu15.04以降)


システムシャットダウン時にmysqlを手動で止める?
# systemctl stop mysql.service && systemctl disable mysql.service


以下の対策では再発した。
shutdown時に"A stop job is running for MySQL Community Server" と表示され10分間停止してしまう現象への対処

( askubuntu.com/questions/615129/systemd-mysql-wont-stop より)
# chgrp mysql /etc/mysql/debian.cnf
# chmod 640 /etc/mysql/debian.cnf
# cp /lib/systemd/system/mysql.service /etc/systemd/system/
# chmod 755 /etc/systemd/system/mysql.service

/etc/systemd/system/mysql.service を編集する。
  [Service]セクションに次の行を書き込む。
    ExecStop=/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown

変更をsystemdに登録する。
  # systemctl daemon-reload

以下の対策はxubuntu16.04では改善されなかった。
( askubuntu.com/questions/615129/systemd-mysql-wont-stop より)
# cat /etc/mysql/debian.cnf
    password = xxxxx を確認する。

$ mysql -u root -p

mysql> GRANT ALL PRIVILEGES ON *.* TO 'debian-sys-maint'@'localhost' IDENTIFIED BY 'xxxxx' ;
mysql> flush privileges;

以下の対策はxubuntu16.04では改善されなかった。
  # cp /lib/systemd/system/mysql.service /etc/systemd/system/
  # chmod 755 /etc/systemd/system/mysql.service

OpenVPNインストール ルーティング方式 Easy-RSA3利用、TLS認証無し版

2019 Apr. 27.
2018 Oct. 07.
2018 Sep. 30.
2018 Sep. 27.
2018 Sep. 02.

インストール

こちら(https://qiita.com/noraworld/items/2fe6be489e1d93c748b8) を参照

 

 プログラムインストール

# apt install openvpn
$ cd ~/YOUR-WORK-DIR
$ git clone https://github.com/OpenVPN/easy-rsa.git
 

初期設定

$ cd ~/YOUR-WORK-DIR/easy-rsa/easyrsa3


$ ./easyrsa init-pki

 

 CA証明書生成

以後入力するパスフレーズはすべて同じにしておいた方が楽。
CA名称は "ホスト名+OS名" にした。 
$ ./easyrsa build-ca
$ sudo cp pki/ca.crt /etc/openvpn/

 

サーバ証明書生成

$ ./easyrsa build-server-full server nopass
$ sudo cp pki/issued/server.crt /etc/openvpn/
$ sudo cp pki/private/server.key /etc/openvpn/

 

DH鍵生成

$ ./easyrsa gen-dh
$ sudo cp pki/dh.pem /etc/openvpn/
 

クライアント証明書生成

$ ./easyrsa gen-crl
$ sudo cp pki/crl.pem /etc/openvpn/
$ sudo chmod o+r /etc/openvpn/crl.pem

 

サーバー設定ファイル記述

# touch /etc/openvpn/server.conf
 
/etc/openvpn/server.confを編集
###########
port   1194
proto  udp
dev    tun
 
cipher AES-256-CBC 
 
ca          ca.crt
cert        server.crt
key         server.key
dh          dh.pem
crl-verify  crl.pem

ifconfig-pool-persist ipp.txt

server 10.8.0.0 255.255.255.0

push "redirect-gateway def1 bypass-dhcp"
push "route 10.8.0.0 255.255.255.0"
push "dhcp-option DNS 8.8.8.8"

client-to-client
keepalive 10 120
comp-lzo

user  nobody
group nogroup

persist-key
persist-tun

status      /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

verb 3 
###########


 

ファイアウォール設定

# ufw allow 1194/udp
# ufw reload
 

IPフォワーディング設定

 /etc/default/ufw を編集する
  DEFAULT_FORWARD_POLICYをDROPからACCEPTに変更する
    - DEFAULT_FORWARD_POLICY="DROP"
    + DEFAULT_FORWARD_POLICY="ACCEPT"
 
 IPフォワーディングを有効化
  /etc/ufw/sysctl.confを編集する
   net.ipv4.ip_forward=1の一行をアンコメントする
    - # net.ipv4.ip_forward=1
    + net.ipv4.ip_forward=1
 

IPマスカレード有効化

 ifconfigでネットワークポート名を確認する( enp0s7 とか)

 /etc/ufw/before.rulesを編集する
  一番下の行にCOMMITと書かれているはずなので、この下に以下を追加する
   COMMIT
   +
   + *nat
   + :POSTROUTING ACCEPT [0:0]
   + -A POSTROUTING -s 10.8.0.0/24 -o enp0s7 -j MASQUERADE
   + COMMIT
 
 # ufw reload
 
Logローテーション設定
こちら 

 

OpenVPN起動

# systemctl start openvpn@server
もしくは
# systemctl start openvpn

 起動確認
 $ ps ax -f | grep openvpn | grep -v grep
 
 $ systemctl status openvpn@server
 もしくは
 $ systemctl status openvpn
 
  Active: active (running) の表示を確認する
 

OpenVPN自動起動設定

# systemctl disable openvpn && systemctl enable openvpn@server
もしくは
# systemctl disable openvpn@server && systemctl enable openvpn
 
  確認 
   $ systemctl is-enabled openvpn openvpn@server
 

クライアント用秘密鍵の生成

$ cd ~/YOUR-WORK-DIR/easy-rsa/easyrsa3 
$ ./easyrsa build-client-full HOGE
  HOGEは "サーバー名+サーバーOS+クライアント端末名" とした。
  「$ ./easyrsa build-client-full HOGE nopass」とすれば接続時パスワード不要。
 
$ mkdir ~/CLIENT-FILE-DIR
$ sudo cp /etc/openvpn/ca.crt ~/CLIENT-FILE-DIR/
$ cp pki/issued/HOGE.crt ~/CLIENT-FILE-DIR/
$ cp pki/private/HOGE.key ~/CLIENT-FILE-DIR/
$ sudo chown USER:USER ~/CLIENT-FILE-DIR/ca.crt
$ chown USER:USER ~/CLIENT-FILE-DIR/HOGE.crt
$ chown USER:USER ~/CLIENT-FILE-DIR/HOGE.key
  USER: VPNサーバに現在ログインしているユーザのユーザ名 
 

接続するクライアントに鍵ファイルをダウンロード

$ scp ~/CLIENT-FILE-DIR/ca.crt CLIENT
$ scp ~/CLIENT-FILE-DIR/HOGE.crt CLIENT
$ scp ~/CLIENT-FILE-DIR/HOGE.key CLIENT
 


設定

WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this

This is nothing to worry about.
https://support.hidemyass.com/hc/en-us/articles/202720436-Auth-nocache-Warning-in-OpenVPN-connection-log


WARNING: cipher   local='cipher BF-CBC'  remote='cipher AES-256-CBC'

クライアントの暗号化方式を AES-256-CBS に指定する。
参考サイト


VPN経由でアクセスするLAN内の各種サーバーの設定

http://rokkonet.blogspot.com/2018/05/openvpn.html


OpenVPNに関する用語


2018 Sep. 02.



 https://wiki.parabola.nu/Easy-rsa より

PKI : a Public Key Infrastructure

 a Public Key Infrastructure (PKI) consists of:
    a public master Certificate Authority (CA) certificate and a private key;
    a separate public certificate and private key pair for each server;
    a separate public certificate and private key pair for each client.

easy-rsa
    It initialize a new PKI and generate a CA keypair that will be used to sign certificates.

ubuntu17.10以降のnetwork設定

2018 Sep. 02.

https://qiita.com/zen3/items/757f96cbe522a9ad397d より

設定変更

/etc/netplan/xxx.yamlを編集する。
 network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: no
      dhcp6: no
      addresses: [192.168.1.70/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [192.168.1.1, 8.8.8.8, 8.8.4.4]

設定反映

$ netplan apply

nfsサーバーインストール

2018 Sep. 02.

# apt install nfs-kernel-server

/etc/exports設定
  /DIR 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)

ファイアウォール設定
  portmapper: 111/tcp, 111/udp
  nfs: 2049/tcp, 2049/udp

  # ufw allow proto tcp from 192.168.1.0/255.255.255.0 to any port 111
  # ufw allow proto udp from 192.168.1.0/255.255.255.0 to any port 111
  # ufw allow proto tcp from 192.168.1.0/255.255.255.0 to any port2049
  # ufw allow proto udp from 192.168.1.0/255.255.255.0 to any port2049
  # ufw reload

HDDパーティションのUUIDの確認とUUIDを使ったマウント

2018 Sep. 02.

ハードディスクパーティションのUUID確認
# blkid /dev/sda1

パーティションのマウント
# mount UUID=YOUR-PARTITION-UUID /DIR
  UUIDを引用符で囲まない。


2018年9月1日土曜日

android emulatorをqemu kvm で動かす

2018 Sep. 02.
2018 Sep. 01.

・# apt install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils virtinst cpu-checker

  インストール結果確認
   # kvm-ok
   INFO: /dev/kvm exists
   KVM acceleration can be used

・kvmグループにユーザーを追加する

・# chown USER:kvm /dev/kvm
 もしくは
 # chmod a+x /dev/kvm

apt パッケージ更新禁止設定

2018 Sep. 01.

dpkg –set-selections での設定
 https://server-setting.info/debian/debian-no-apt-upgrade.html

pinでの設定
 https://server-setting.info/debian/debian-no-apt-upgrade.html

 https://yoheikikuta.github.io/ubuntu-kernel/

apt-mark hold での設定
 https://teratail.com/questions/108796

xfce4 ウィンドウを前面に出さずにマウスでスクロール可能で、ウィンドウをクリックしたらフォーカスを得る設定

2018 Sep. 01.

メニュー→設定→ウィンドウマネージャー→フォーカス→
フォーカスモデル→「クリックでフォーカス」にチェックを入れる

メニュー→設定→ウィンドウマネージャー→フォーカス→
フォーカスで前面に出す→「ウィンドウがフォーカスを取得した場合自動的に前面に出す」にチェックを入れる

systemdによる時刻合わせ

2019 Jun. 22.
2018 Sep. 01.

NTPクライアント機能を有効化
# timedatectl set-ntp true

設定ファイル
/etc/systemd/timesyncd.conf
  NTP=ntp.nict.jp
  FallbackNTP=ntp.ubuntu.com  # 予備サーバー


 
再起動
# systemctl restart systemd-timesyncd.service
 
確認
$ systemctl -l status systemd-timesyncd
もしくは 
$ timedatectl

2018年8月29日水曜日

C言語 ポインタ宣言の読み方

2016 Dec. 25.

http://kmaebashi.com/programmer/pointer.html 参照方。
 
( http://news.mynavi.jp/articles/2008/04/18/pointer/002.html より)
char *ap[3];
  あるapという名前のものがある
    ↓
    apは配列の先頭アドレスを表す定数で、配列要素ap[x]を求めることができる
    ↓
    ap[x]はポインタであり、その指し示す先の「*ap[x]」はchar型である
    以上により、「char *ap[3];」が「ポインタの配列」を宣言している

char **pp;     ← 「char型へのポインタ」へのポインタppを宣言
  char *ap[3];   ← 「char型へのポインタ」を要素とする配列ap(要素数3)を宣言
  char a[5];     ←  char型を要素とする、要素数5の配列aを宣言

ap[2] = a;                    ← ap[2](ポインタ)にaのアドレス定数を代入
a[3] = 'Y';                   ← a[3]には文字'Y'を代入
pp = ap;                      ← apのアドレス定数はポインタのポインタに代入可
printf("%c\n", ap[2][3]);     ← apに[ ]の添字を2つ付けて内容を読む
printf("%c\n", pp[2][3]);     ← ppを使っても同様に記述できる
printf("%c\n", *(*(ap+2)+3)); ← ポインタとして記述する場合はこうなる
printf("%c\n", *(*(pp+2)+3)); ← ppを使う場合も同様
printf("%c\n", *(ap[2]+3));   ← 添字の[ ]とポインタの*が混在した記述も可能
printf("%c\n", *(pp[2]+3));   ← ppを使う場合も同様
printf("%c\n", (*(ap+2))[3]); ← 添字の[ ]とポインタの*を入れ替えた場合
printf("%c\n", (*(pp+2))[3]); ← もちろんppを使っても同様
 
( http://news.mynavi.jp/articles/2008/04/18/pointer/003.html より)
「配列へのポインタ」の宣言の「char (*pa)[5];」は、次のように考えます。

     あるpaという名前のものがある
     ↓
     paはポインタであり、paが指し示す先(*pa)は、何らかの要素数5の配列全体である
     ↓
    その配列の各要素「(*pa)[x]」はchar型である
    「配列へのポインタ」は、単に配列の先頭アドレスを指したポインタではありません。このポインタ(pa)は所定の大きさの配列全体を指しており、paをインクリメントすると、paが指し示す配列のサイズ分(5バイト)、アドレス値が加算されます。このため、pa自体はポインタであっても、宣言時にはそのポインタの指し示す先の配列の大きさを指定する必要があります。
    なお、paの宣言では、[5]という値を指定していますが、実際の配列用のメモリは(宣言しただけでは)確保されません。

( http://blog.tojiru.net/article/426537111.html より )
日本語らしくしたい場合は、最後に順番をひっくり返します。

(1) 識別子を探す。

(2) 識別子の両隣から読み始めるが、次の順番で結合される。
  1. 優先度を表す()
  2. 関数を表す()、配列を表す[]
  3. ポインタを表す*
(3) 配列はarray(要素数) of ...
      関数はfunction(引数) returning ...
      ポインタはpointer to ...
      という風に英語で置き換えてゆく。

(4) 最後に派生元の型(intとかfloatとか)を付けて終わり。

  *a[10]*a(void)みたいに両側に何か書いてある時は、配列や関数の方が勝つ。

 int (*(*a(void))[10])(void);
   a is function(void) returning pointer to array(10) of pointer to function(void) returning int.
   aは、int を返す関数(void) へのポインタ の配列(要素数10) へのポインタ を返す関数(void)
 
 void (*signal(int, void (*)(int)))(int);
   signal is function(int, pointer to function(int) returning void) returning pointer to function(int) returning void.
   signalは、void を返す関数(int) へのポインタ を返す関数(int, voidを返す関数(int) へのポインタ) 


( https://naofumi.castle104.com/c%E8%A8%80%E8%AA%9E%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E5%AE%A3%E8%A8%80%E3%81%AE%E8%AA%AD%E3%81%BF%E6%96%B9/ より ) 
  1. 最初は変数名から出発して、型まで
    char *(*(**foo [][8])())[];
    foo ischar
  2. 変数名の右の[]
    char *(*(**foo [][8])())[];
    foo is array of … char
  3. さらに右に行って[8]
    char *(*(**foo [][8])())[];
    foo is array of array of 8 … char
  4. )にぶつかったので、変数名の左のポインタ演算子*を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to … char
  5. さらにその左のポインタ演算子*
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to … char
  6. ()の中の処理が終わったので、右に移動。そこには関数を表す()があります
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning … char
  7. ここで)にぶつかるので、左に戻ってポインタ演算子*を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning pointer to … char
  8. 左に行くと(にぶつかるので、この()は処理が終了。次に右に行って[]を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning pointer to array of … char
  9. これで右端まで行ったので、左に戻って一番左のポインタ演算子*を処理
    char *(*(**foo [][8])())[];
    foo is array of array of 8 pointer to pointer to function returning pointer to array of pointer to char


2018年8月26日日曜日

NVIDIA Corporation GF108 [GeForce GT630]のドライバのubuntu系へのインストール

2018 Sep. 02.
2018 Aug. 26.

# apt install nvidia-352

大画面表示になったので 、表示フォントを3ポイント上げた。

2018年8月19日日曜日

BitbucketへのSSH認証導入

2018 Aug. 19.
 
$ cd ~/.ssh
$ mkdir bitbucket
$ cd bitbucket
$ ssh-keygen -t rsa -C YourMail@Address
 Enter file in which to save the key の問いに ~/.ssh/bitbucket/id_rsa と入力する。
 パスワードの設定を2回問われるが、Enterのみを入力する。
  
$ mv id_rsa id_rsa.bitbucket
$ chmod 600 id_rsa.bitbucket

~/.ssh/config に次を記載する
 Host bitbucket.org
  HostName bitbucket.org
  IdentityFile ~/.ssh/bitbucket/id_rsa.bitbucket
  User git
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes
 
https://bitbucket.org にアクセスし、
「Manage Account」→「SSH keys」→「Add Key」と鍵設定画面に移る。
 Label:任意の文字列(クライアントデバイス名とか)
 Key:「id_rsa.bitbucket.org.pubの内容(メールアドレスを含む)」コピー&ペースト
 「鍵追加」ボタンを押す。

接続テスト
$ ssh -T git@bitbucket.org
(表示) 
 conq: logged in as ユーザ名.
You can use git or hg to connect to bitbucket. Shell access is disabled.
 
それまでhttps/sslで認証していたリポジトリは削除して再クローンを要するみたい。
 

ruby 配列を値とするハッシュ

2018 Aug. 19.


http://simanman.hatenablog.com/entry/2013/09/24/211044

  list = Hash.new{|hash, key| hash[key] = []}
  Hash.newにブロックを与えるとブロック引数の1番目がhash自身、2番目がkeyとなります。
  そこで上記のように配列を定義してあげると、keyごとに配列を初期化することが出来るようになります。

  RubyはHashのデフォルト値をHash.newの引数として渡すことで実現できますが、配列を渡すと同じ参照になってしまうのでうまくいきません。
    失敗例:list = Hash.new([])

2018年8月18日土曜日

ruby Could not locate Gemfile or .bundle/ directory スクリプトのファイル属性を実行可能に

2018 Aug. 18.

rubyスクリプトを起動すると
Could not locate Gemfile or .bundle/ directory
で止まった。

Bundler設定を疑ったが、単にファイル属性に実行可能属性が無いだけだった。

2018年8月17日金曜日

git ブランチの統合

2018 Aug. 17.

devブランチのmasterブランチへの統合

(現在のブランチを確認する)
$ git branch

(devブランチに移る)
$ git checkout dev

(devブランチを最新に)
$ git fetch origin dev
$ git merge FETCH_HEAD

(masterブランチにチェック移る)
$ git checkout master

(masterブランチを最新に)
$ git fetch origin master
$ git merge FETCH_HEAD

(devブランチをmasterブランチに統合)
$ git merge dev

git ブランチの削除

2018 Aug. 17.

ローカルブランチの削除
$ git branch -d BRANCH

リモートブランチの削除
$ git push --delete origin BRANCH

2018年8月15日水曜日

シェルスクリプト テキストファイルを行の文字数順にソート

2018 Aug. 15.

$ cat TextFile | awk '{print length() ,$0}' | sort -n | awk '{$1 = ""; print}'
    各行の先頭にその行の文字数を書き込み、その数値でソートした後に、awkの$1 = "" によって文字数の数値を削除している。

2018年8月14日火曜日

git ローカルに無いリモートのブランチのローカルへのチェックアウト

2018 Aug. 14.

 リモートとローカルのブランチ一覧を表示
 $ git fetch
$ git branch -a

 リモートのorigin/BRANCHをローカルBRANCHにチェックアウトする
$ git checkout -b BRANCH origin/BRANCH
 
 
 

xfceのパネルにプログラム起動アイコンを入れる

2018 Aug. 14.

パネルを右クリックして「パネル」>「新しいアイテムの追加」を選択

「ランチャ」を選択して「追加」ボタンをクリック

「新しいアイテムの追加」ウィンドウは閉じる

パネルに置かれたランチャを右クリックして「プロパティ」を選択

新規追加のボタンをクリック

 ランチャを作成する

2018年8月13日月曜日

ubuntu系linuxインストール

2019 Oct. 14.
2019 Jan. 04.
2018 Dec. 01.
2018 Nov. 04.
2018 Oct. 14.
2018 Oct. 12.
2018 Aug. 13.
(install) DVDからlinuxディストリビューションをインストール
(video)  nvidia-xxxインストール
(user) グループ、ユーザ設定
(network) IPアドレス設定(dhcpから固定アドレスに変更)
(network) /etc/hosts設定
(TCP Wrapper) /etc/hosts.deny /etc/hosts.allow 基本設定
sshサーバー
  ポート設定
    ssh設定ファイル
  TCP Wrapper設定(/etc/hosts.deny /etc/hosts.allow)
  netfilter設定(ufw)
(nfs server)(nfs client) portmap rpcbind nfs-commonインストール
(file system) fstab設定
システムワイドパス設定
ユーザーのumask設定
sshクライアント
時刻合わせ
anti-virusソフトインストール
  Sophos Anti-Virus for Linux

プリンタインストール
ルータ ポート転送設定
sambaインストール
OpenVPNインストール
javaインストール
    # apt install default-jdk
mysqlインストール
phpインストール
apache2インストール
  80番ポート開放状況を確認する(ufw status)
pt2・recpt1インストール
epgrec_unaインストール
tssplitter_lite, ffmpegインストール
gitインストール bitbucket設定
rbenv ruby bundlerインストール
grive2インストール
rootユーザーcron設定
一般ユーザーcron設定
 cronでのPATH, HOME, RUBYLIB等を設定
sinatraインストール・設定
mysqlデータ移行
wol設定
RTMPサーバーインストール

2018年8月1日水曜日

シェルスクリプト 空白を含む文字列を格納した変数の展開

2018 Nov. 11.
2018 Aug. 01.

Str=' ab     cd '

COMMAND $Str
シェル展開により
COMMAND  ab     cd 

echo $Str
シェル展開により
echo  ab     cd
    出力 'ab cd'  ( ' は出力に含まない)
     Strの先頭と末尾の空白が落ちる。abとcdの間の空白は1つになる。

cp $Str
シェル展開により
cp  ab     cd 
 (ファイルabのファイルcdへのコピー)


COMMAND "${Str}"
シェル展開により
COMMAND ' ab     cd '

echo "${Str}"
シェル展開により
echo ' ab     cd '
    出力 ' ab     cd '  ( ' は出力に含まない)
      Strの先頭と末尾の空白が残る。abとcdの間の空白もすべて残る。

cp "${Str}"
シェル展開により
cp ' ab     cd '
 (ファイル「 ab     cd 」のコピー先が指定されていない)

2018年7月29日日曜日

bashならできる変数内文字列置換

2018 Jul. 29.

${変数名/置換前文字列/置換後文字列}
  最初に一致した部分のみを置き換える。

${変数名/置換前文字列//置換後文字列}
  すべての一致部分を置き換える。

bash 文字列の末尾の削除

2018 Jul. 29.

bashでの文字列Strの末尾の削除
echo ${Str/%?/}

2018年7月28日土曜日

grub2の起動ディスクMGRへのインストール

2018 Jul. 28.

/と/bootが同じパーティションの場合

    #  grub-install  /dev/HDD

/と/bootが異なるパーティションの場合

    #  grub-install --root-directory=/  /dev/HDD

ubuntu系でのビデオカードと利用ドライバの調べ方

2018 Jul. 28.

ビデオカード

$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:0d.0 ==
modalias : pci:v000010DEd000003D0sv00001028sd0000020Ebc03sc00i00
vendor   : NVIDIA Corporation
model    : C61 [GeForce 6150SE nForce 430] (Inspiron 531)
driver   : nvidia-304 - third-party free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin

 ドライバ

$ lshw -c video 2>&1 | grep driver
       設定: driver=nouveau latency=0

NFSクライアント設定

2018 Jul. 28.

xubuntu18.04, xubuntu16.04


portmap をインストールし、再起動する
    # apt-get install portmap nfs-common
    # shutdown -r now

/etc/fstab へ書き込む
    HOST:/DIR  /CLIENT-DIR  nfs  rw,noatime,intr,hard  0  0

2018年7月21日土曜日

シェルスクリプト 文字列から先頭の1文字を削除した上で、直前が\もしくは"ではない"までを最短一致で削除する

2018 Jul. 21.

bash上で、文字列Lineから先頭の1文字を削除した上で、直前が\もしくは"ではない"までを最短一致で削除する

LeftLine=${Line:1:$(( ${#Line} - 1 ))}  # 先頭文字削除
DelStr=$(echo $LeftLine | grep -oP -e '^.*?[^\\"]"[^"]')  # 最短一致削除文字列取得
DelStr=${DelStr/%?/}  # 余分に取得した末尾文字を削除
DelStr=$(echo $DelStr | sed -e 's/\\/\\\\/g')  # \を\でエスケープし\\に
echo $LeftLine | sed -e s/${DelStr}//  # 削除実行

${parameter/pattern/string}
パターンの置換。 pattern が展開され、 パス名展開の場合と同じようなパターンを作ります。 parameter の展開が行われ、 その値のうち pattern に最長一致する部分が string に置換されます。 pattern が / で始まる場合には、pattern に マッチした部分は全て string に置換されます。 そうでない場合には、最初にマッチした部分だけが置換されます。 pattern が # で始まる場合には、パターンは parameter を展開した値の先頭にマッチしなければなりません。 pattern が % で始まる場合には、パターンは parameter を展開した値の末尾にマッチしなければなりません。 string が空の場合には pattern にマッチした部分は削除されます。 またこの場合には、pattern の後に続く / は省略可能です。 parameter が @ または * である場合、置換操作は全ての位置パラメータに順番に適用され、 展開結果はリストとして得られます。 parameter が @ または * が添字になっている配列変数である場合、 置換操作は配列の全ての要素に順番に適用され、 展開結果はリストとして得られます。

シェルスクリプト 文字列から直前に\(バックスラッシュ)が無い"(二重引用符)までを削除する

2018 Jul. 21.

Srch=$(echo $Line | grep -oP '^.*?\\".*?[^\\]"' | sed -e 's/\\/\\\\/g')
echo $Line | sed -e s/${Srch}//

「直前に\(バックスラッシュ)が無い"(二重引用符)まで」の検索
  原形 ^.*?\".*?[^\]"
  grepに使う時 '^.*?\\".*?[^\\]"'
  sedに使う時 '^.*?\\".*?[^\\]"'

sedの検索文字列内での\(バックスラッシュ)
  '(シングルクォーテーション)で囲むと
    シェルではそのまま読み込まれて
    sedにおいて\(バックスラッシュ)が状況に応じてエスケープ文字に解釈される

  '(シングルクォーテーション)で囲まないと
    シェルで読み込まれる時に\が状況に応じてエスケープ文字に解釈され
    sedにおいても\が状況に応じてエスケープ文字に解釈される
    \をたくさん書く必要がある

2018年7月20日金曜日

sedでのバックスラッシュの扱いについて

2018 Jul. 20.
2018 Jul. 19.

sedの s/regexp/replacement/ におけるregexp内の文字としての\には\\とエスケープする必要がある。

ケースA(bash上のsedでうまくいかない)
Str='"wr\"ddadf\"ab",a'
Search='"wr\"ddadf\"ab"'
echo $Str | sed -e s/${Search}//
結果: "wr\"ddadf\"ab",a
(期待していた結果: ,a )

(検索文字列Searchを短くしていくと)
ケースB(うまくいかない)
Str='"wr\"ddadf\"ab",a'
Search='"wr\"ddadf\'
echo $Str | sed -e s/${Search}//
結果: sed: -e expression #1, char 15: `s' コマンドが終了していません

ケースC(Str内の\を\\とエスケープするとうまくいく)
Str='"wr\"ddadf\"ab",a'
Search='"wr\\"ddadf\\'
echo $Str | sed -e s/${Search}//
結果: "ab",a

ケースD(うまくいかない)
Str='"wr\"ddadf\"ab",a'
Search='"wr\"d'
echo $Str | sed -e s/${Search}//
結果: "wr\"ddadf\"ab",a
(期待していた結果: dadf\"ab",a )

ケースE(Str内の\を\\とエスケープするとうまくいく)
Str='"wr\"ddadf\"ab",a'
Search='"wr\\"d'
echo $Str | sed -e s/${Search}//
結果: dadf\"ab",a

ケースF(うまくいかない)
Str='"wr\"ddadf\"ab",a'
Search='"wr\"'
echo $Str | sed -e s/${Search}//
結果: "wr\"ddadf\"ab",a
(期待していた結果: ddadf\"ab",a )

ケースG(Str内の\を\\とエスケープするとうまくいく)
Str='"wr\"ddadf\"ab",a'
Search='"wr\\"'
echo $Str | sed -e s/${Search}//
結果: ddadf\"ab",a

ケースH(うまくいかない)
Str='"wr\"ddadf\"ab",a'
Search='"wr\'
echo $Str | sed -e s/${Search}//
結果: sed: -e expression #1, char 8: `s' コマンドが終了していません
考察:次のケースFとの違いは\なので、\が続く/のエスケープ文字に解釈されているのか?

ケースI(Str内の\を\\とエスケープするとうまくいく)
Str='"wr\"ddadf\"ab",a'
Search='"wr\\'
echo $Str | sed -e s/${Search}//
結果: "ddadf\"ab",a

ケースJ(うまくいく)
Str='"wr\"ddadf\"ab",a'
Search='"wr'
echo $Str | sed -e s/${Search}//
結果: \"ddadf\"ab",a (期待どおり)

2018年7月17日火曜日

grep 文字列の先頭から、直前に\が無い"(二重引用符)までの文字列の最短一致検索

2018 Jul. 20.
2018 Jul. 19.
2018 Jul. 17.

文字列の先頭から、直前に\(バックスラッシュ)が無い"(二重引用符)までの文字列の最短一致検索

$ grep -oP '^.*?\\".*?[^\\]"'

 -P で最短一致が可能なPearl正規表現とし、検索文字列中の?で最短一致指定、-o で一致文字列を出力

変数への結果格納
$ Result=$(echo $Str | grep -Po '^.*?\\".*?[^\\]"')

シェル シングルクォーテーションで囲んだバックスラッシュ、アスタリスク*、二重引用符"(ダブルクォーテーション)の扱い

2018 Jul. 17.

シェルでのシングルクォーテーションで囲んだ文字列では、
\は\\と記し
*や"はそのまま記す。

$ echo $String | grep '^.*\\"'

grepでの最短一致検索

2018 Jul. 21.
2018 Jul. 17.

grepに -P オプションを付ける
 最短一致可能なPearl正規表現が利用可能となる

検索文字列に ? を付ける
 ?に続く文字列の最短一致となる
 (最左最短一致なので検索文字列の先頭には注意が必要)
  qiita.com/anqooqie/items/191ad215e93237c77811

先頭からabまでの最短一致検索
$ echo adabfdabdfaabd | grep -P '^.*?ab'

-o オプションを付けると、行全体ではなく、マッチした文字列だけが1行1文字列で出力される。
$ echo adabfdabdfaabd | grep -Po '^.*?ab'

2018年7月8日日曜日

grepの検索文字列に$(ドル記号)を含める方法

2018 Jul. 08.

rcmdnk.com/blog/2013/10/28/computer-bash-linux/

bash上でのgrepで検索文字列に$(ドル記号)を含める方法

$を含む文字列の検索

ドル記号($)は変数の参照に使われるため、エスケープせずに単純にこれを書くと続く文字列の変数を 参照する様な形になって、大概の場合は未定義変数=空文字で 全ての行が該当してしまう。

ドル記号をエスケープしてダブルクォートするか、シングルクォートで囲むことで囲み内を展開しないようにする。
grep "\$abc"
grep '$abc'

$のみの検索

grep "\\$"
grep '\$'

シェルスクリプトの位置パラメータ/コマンドライン引数の一括展開

2018 Jul. 08.

fumiyas.github.io/2016/12/15/positional-parameters.sh-advent-calendar.html

"$*"
すべての値の間にスペース ` ` が差し込まれた1つの文字列に展開される。
展開の結果は元にように個別の値にはならず、スペースが差し込まれたひと塊の一つの値になる。
ダブルクォートに括られているため、展開後にワード分割はされない。
同様にパス名展開やブレース展開なども適用されない。

"$@"
位置パラメータの数だけ展開される。
パラメーターの数は変化しない。
ワード分割や各種展開もされない。

$* と $@ は同じ
位置パラメータの各値がそれぞれ個別に展開された後、個別にワード分割やパス名展開などが適用される。



2018年7月7日土曜日

文字列がマッチする数をカウントするシェルスクリプト

2018 Jul. 07.

server.etutsplus.com/shell-script-substr-count/

(1) 検索対象文字列から検索する文字列を見つけて改行文字「\n」を付けてマッチする数を行数にする
(2) "grep -c"で検索する文字列が何回現れるかカウントする

  echo $Line | sed "s/${Str}/${Str}\n/g" | grep -c "${Str}"

2018年6月24日日曜日

画像をアスペクトを保持して縮尺/拡大して、指定位置に表示する

2018 Jun. 24.

$ convert -resize WIDTHxHEIGHT INFILE.jpg jpeg:- | display -geometry +X+Y jpeg:-

 画像の横長x縦長を -resize で指定する。アスペクト比は保持される。
 パイプに渡す画像形式を TYPE:- で指定する。
  TYPE : jpg, jpeg, gif, png, bmp ...
 画像の表示位置の左上の座標を -geometry で指定する。

  $ convert -resize 300x200 INFILE.jpg jpeg:- | display -geometry +15+50 jpeg:-

2018年6月19日火曜日

「git fetch origin master」は

www-creators.com/archives/1097#git_fetch_origin_mater より
「git fetch origin master」は、リモートレポジトリ「origin」にあるブランチ「master」を、ローカルのリモート追跡ブランチに反映させる。という意味のコマンドです。

2018年6月17日日曜日

Gitの作業パターン

2018 Jun. 20.
2018 Jun. 19.
2018 Jun. 16.

A-1)リモートリポジトリ作成
A-2)リモートリポジトリのローカルへのclone

B-1)git fetch origin master 
B-2)git merge FETCH_HEAD

3)ローカルリポジトリでのファイル作成
4)ローカルリポジトリ内のファイルのadd
  サブディレクトリ作成時はその中にファイルが無ければcommitできない?
      $ git add -A
5)ローカルリポジトリのcommit
      $ git commit -a -m "MESSAGE"
6)ローカルリポジトリ内のリモートリポジトリへのpush
      $ git push origin master