かきすて

正しいかどうかよくわからない知識をよくわからないままとりあえず公開してみようというコンセプトで運営しています。

bashスクリプトで自分と同じ名前のプロセス数を数えようとしたら1つ多く表示される、変数に結果を入れようとしたときだけ

雑に排他を実装しようとしたのだが。

zatsu_check.sh

#!/bin/bash
echo '1. 普通に「ps -ef | grep $0 | grep -v grep」を実行した場合'
ps -ef | grep $0 | grep -v grep
echo

echo '2. 「$(ps -ef | grep $0 | grep -v grep)」の場合'
PROCESS1=$(ps -ef | grep $0 | grep -v grep)
cat <<EOT
$PROCESS1
EOT
echo

echo '3. 「`ps -ef | grep $0 | grep -v grep`'」の場合
PROCESS2=`ps -ef | grep $0 | grep -v grep`
cat <<EOT
$PROCESS2
EOT

このように結果を変数に入れようとすると、結果が1行増えてしまう。以下の2番と3番。

$ sh zatsu_check.sh
    1. 普通に「ps -ef | grep $0 | grep -v grep」を実行した場合
    user     69679   9435  0 18:31 pts/3    00:00:00 sh zatsu_check.sh

    2. 「$(ps -ef | grep $0 | grep -v grep)」の場合
    user     69679   9435  0 18:31 pts/3    00:00:00 sh zatsu_check.sh
    user     69707  69679  0 18:31 pts/3    00:00:00 sh zatsu_check.sh

    3. 「`ps -ef | grep $0 | grep -v grep`」の場合
    user     69679   9435  0 18:31 pts/3    00:00:00 sh zatsu_check.sh
    user     69712  69679  0 18:31 pts/3    00:00:00 sh zatsu_check.sh

要するに$()もしくは``でサブシェルが実行され、そのプロセス名が親シェルと同じになるらしい。 なので、真面目に排他を実装しよう、 とはならず、+1を加味した作りになったのであった。罪深い。ほんとすいません。

参考

https://teratail.com/questions/65510

http://tetsuyai.hatenablog.com/entry/20110720/1311131803

CentOS6にアップグレードツール入れようとしたらpreupgrade-assistantがないって言われる

CentOS 6.5からCentOS 7.0へのアップグレード(補足トラブル:対処) - Marlock Homes Diary
の手順4でこける。

# yum install --enablerepo=upg redhat-upgrade-tool preupgrade-assistant-contents
	--- 略 ---
	Error: Package: 1:redhat-upgrade-tool-0.7.22-3.el6.centos.noarch (upg)
	           Requires: preupgrade-assistant >= 1.0.2-4
	Error: Package: preupgrade-assistant-contents-0.5.14-1.el6.centos.noarch (upg)
	           Requires: preupgrade-assistant(x86-64) >= 1.0.2-14
	--- 略 ---

32bit版のCentOS6をアップグレードしようとしたから。
CentOS7は32bit版ない。

PL/pgSQLでパーティショニングしたテーブルにINSERTしたときROW_COUNTがとれない

PL/pgSQLでは

GET DIAGNOSTICS count = ROW_COUNT;

という感じの記述をすると、直前のクエリで影響を受けた行数をとることができる。
が、パーティショニングしてるテーブルにINSERTした場合、必ず0が入ってしまう。PostgreSQL9.1.12で確認。
親テーブルでなく、継承した子テーブルに直接INSERTすると、ちゃんととれる。

なぜとれないのか

たぶん、BEFORE INSERTのトリガでNULLを返してるから。

PostgreSQLでパーティショニングを実現するとき、親テーブルにBEFORE INSERTトリガを張って、適切な子テーブルに振り分け、親テーブルにデータが入ってしまわないようにNULLを返すようにすると良いよと、公式のドキュメントに書いてある。ので、今回この現象を確認したテーブルも、そういう実装にしていた。
https://www.postgresql.jp/document/9.3/html/ddl-partitioning.html

で、BEFORE INSERTでNULLを返したときの挙動はこんな感じらしい。

BEFOREとして発行された行レベルトリガがNULLを返す場合には、トリガマネージャに実際の行への操作を取りやめるように通知します(つまり、その後にトリガが発行されず、そのINSERT/UPDATE/DELETEはその行に対して実行されません)。

https://www.postgresql.jp/document/9.2/html/plpgsql-trigger.html

「行への操作を取りやめ」てるので、INSERTした行数が0ってことになるのだと思う。

batsを実行した時、「@test: コマンドが見つかりません」と言われる

% bats test.bats
/tmp/bats.86117.src: 行 27: @test: コマンドが見つかりません

テストケースのタイトルの後の、"{"の前のスペースは必須らしい。

修正前

@test "testcase1"{
  # "testcase1"と{の間にスペースがないとエラー!

修正後

@test "testcase1" {
  # "testcase1"と{の間にスペースがあると動く!

sudoのときだけrvmで入れたrubyを使ってくれない

sudoのときだけrvmで入れたrubyじゃなくてもとから入ってた/usr/bin/rubyを使うのでgemを入れるとき困った。

$ ruby -v
ruby 1.9.3p545 (2014-02-24 revision 45159) [i686-linux]
$ sudo ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [i386-linux]
	
$ which ruby
/usr/local/rvm/rubies/ruby-1.9.3-p545/bin/ruby
$ sudo which ruby
/usr/bin/ruby

原因

sudoのとき$PATHが引き継がれてなかった。
以下のページの通りにして解決。

$ sudo visudo

を叩いて、

Defaults    env_keep +=  ほにゃららら

が書いてある行を探そう。
それらの直下に

Defaults    env_keep +=  "PATH"

を追加し、

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
↓
# Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

コメントアウトすれば、PATHが通るようになります。

CentOS で sudo 時に実行ユーザーのPATHを引き継ぐ - Qiita

knife soloが秘密鍵のパスフレーズを聞いてくれない

$ knife solo cook -i ~/.ssh/id_rsa hoge@hoge.example.com

Enter the password for hoge@hoge.example.com
ERROR: Net::SSH::AuthenticationFailed: Authentication failed for user hoge@hoge.example.com

てなる.秘密鍵パスフレーズを聞いてくれるようになる方法もあるのかもしれないけど,わからなかったのでパスフレーズをなくした.

$ openssl rsa -in id_rsa -out id_rsa_nopass
$ chmod 600 ~/.ssh/id_rsa_nopass
$ knife solo cook -i ~/.ssh/id_rsa_nopass  hoge@hoge.example.com

gitwebで「No such projects found」と出てリポジトリが表示されない

404とかではなくただ「No such projects found」と出る。
gitコマンドの場所の指定が違うとこうなるらしい。
/etc/gitweb.confに以下を追記したら動いた。

our $GIT = '/usr/local/bin/git';