Linuxでlsの実行結果をawkで取得する方法
ls -l
などで特定のファイルやディレクトリの所有者やグループなどを取得したいときがあります。
たとえば、rbenv
ディレクトリをls -ld
すると、次のように表示されます。
$ ls -ld /usr/local/rbenv
drwxrwxr-x 10 root rbenv 4096 12月 14 17:40 2013 /usr/local/rbenv/
で、たとえば外部のプログラムから「グループがrbenv
なのかどうかしりたい!」という状況を考えます。
上の例だと、たとえばgrep rbenv
しても、パスの方が引っかかるため、ただしく取得できません。
このやり方について書いてみます。
特定のカラムを取得する
グループなど、特定のカラムを取得する方法として、awk
をつかう方法があります。
以下は、ls
した結果の4番目(グループ)を取得する例です。
$ ls -ld /usr/local/rbenv | awk '{ print $4 }'
この実行結果はrbenv
となります。
グループが特定のものかどうか判断する
上の例で、rbenv
だったらそれを返し、違ったら空を返す、という例を以下に示します。
これは上を単にgrep
すればよいです。
$ ls -ld /usr/local/rbenv | awk '{ print $4 }' | grep rbenv
Chef SoloでExecute Resourceをつかうときのnot_if
などでこれが結構役に立ってきます。
このやり方がうまいやり方かどうか正直分かりませんがOnz
Linuxで環境変数のパスを確認する方法
Linuxでコマンドの場所を探すにはwhichコマンドを使う
とある問題を解決しているときに使ったのでメモ。
たとえばruby
コマンドの場所を探すには、以下のようにwhich
コマンドをつかいます。
$ which ruby
/usr/bin/ruby
コマンドの場所を探したり、コマンドにパスがとおっているか確認するときなど、いろんなときにつかえて便利です。 おわり。
参考記事
rbenv環境下でbundle installしたときにRubyのバージョンがおかしい場合の対処例
足かけ2日ハマり、最後はstackoverflowでロシア人の方に丁寧に手ほどきされながら解決を迎えることができました。
問題の発端
Rails環境を構築していて、試しにbundle install
を実行すると、以下のようなメッセージが表示されました。
Your Ruby version is 1.8.7, but your Gemfile specified 2.0.0
え、でもrbenv
でちゃんとインストールしたしぃ……と思い、ruby -v
を実行すると、やっぱりちゃんとインストールされてる。
どや。
$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
ちなみに、Rubyのシステムのデフォルトは以下のとおり。
$ sudo ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
なので、早い段階でbundle install
がシステムのデフォルトを参照してるのでは? というあたりはついていました。
解決策
bundleが参照しているrubyを調べてみる
とりあえずbundle
がrbenv
じゃなくてシステムのRubyを参照していると思ったので、which
で調べてみることに。
$ which bundle
/usr/bin/bundle
なるほど、bundle
はここにあるんですね。
/usr/bin/bundleをcatしてみる
で、次にこれをcat
してみました。
すると、1行目にこうありました。
#!/usr/bin/ruby
これはシステムのデフォルトを参照してますよ、ということですね。 なので、これをとりあえず以下に変えてみました(対処が適当すぎる)。
#!/usr/local/rbenv/shims/ruby
もちろんうまくいかず。
bundleの場所を疑う
で、いろいろ調べるうちに「bundle
もgem
でインストールしたんだから、rbenv
下にインストールされるはずでは?」「もしかしたらbundle
自体がうまくインストールされてないんじゃ……」と思い、調べてみることに。
$ gem list
*** LOCAL GEMS ***
bigdecimal (1.2.0)
io-console (0.4.2)
json (1.7.7)
minitest (4.3.2)
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
test-unit (2.0.0.0)
……。
bundler
がない!
試しにシステムのデフォルトを見てみると、もちろんbundler
はありました。
$ sudo gem list
*** LOCAL GEMS ***
bundler (1.3.5)
json (1.5.5)
bundleを入れなおす
ということなので、改めてbundler
を入れなおします。
$ su
$ gem install bundler
$ rbenv rehash
で、gem list
をしてみると、
$ gem list
*** LOCAL GEMS ***
bigdecimal (1.2.0)
bundler (1.3.5)
io-console (0.4.2)
json (1.7.7)
minitest (4.3.2)
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
test-unit (2.0.0.0)
あったー!
which bundle
してみると、
$ which bundle
/usr/local/rbenv/shims/bundle
はいったー!
bundle install
してみると、
$ bundle install
(省略)
できたー! おしまい。
補足:なぜシステムの方が使われた?
環境設定のパスを見てみると、次のようになってます。
$ echo $PATH
/usr/local/rbenv/shims:/usr/local/rbenv/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/vagrant/bin
これは左から優先順に適用されます。
つまり、rbenv/shims
下になかったので、usr/bin/
下のbundle
が実行されていたのですね。
とりあえず、なんでChef Soloでレシピを書いているにも関わらずbundler
が入らなかったのか、今から調査します。。。
Chef SoloでVagrant上にMySQLをインストールする方法
つぎはChef SoloでVagrant上にMySQLをインストールしてみます。 すこし手間取りましたが、思ったよりすんなりいきました。
MySQLをインストールする準備
クックブックを作成する
おなじみクックブックを作成します。
名前はmysql
にします。
$ knife cookbook create mysql -o site-cookbooks/
rpmファイルをダウンロードする
MySQLの公式サイトから、rpm
ファイルをダウンロードしてきます。
今回ダウンロードするものは以下のとおりです。
- MySQL-server-5.6.15-1.el6.x86_64.rpm
- MySQL-client-5.6.15-1.el6.x86_64.rpm
- MySQL-devel-5.6.15-1.el6.x86_64.rpm
- MySQL-shared-5.6.15-1.el6.x86_64.rpm
- MySQL-shared-compat-5.6.15-1.el6.x86_64.rpm
ダウンロードしたものは、site-cookbooks/mysql/files/default/
下に配置します。
レシピを編集する
mysql-libsを削除する
MySQL Serverのインストールを試みると、以下のようなエラーが起きました。
ファイル /usr/share/mysql/czech/errmsg.sys (パッケージ MySQL-server-5.6.15-1.el6.x86_64 から) は、パッケージ mysql-libs-5.1.66-2.el6_3.x86_64 からのファイルと競合しています。
いろいろ調べてみると、どうやら標準で入っているmysql-libs
と競合しているようです。
これを消しても、MySQL-shared-compat.rpm
を入れれば問題ないようなので、サクッと消します。
$ vi site-cookbooks/mysql/recipes/default.rb
package 'mysql-libs' do
action :remove
end
/tmp/にrpmをつくる
つぎに、ダウンロードしたMySQLの各ファイルをノード側に配置します。
これはdefault.rb
に以下のように書きます。
cookbook_file '/tmp/MySQL-server.rpm' do
source 'MySQL-server-5.6.15-1.el6.x86_64.rpm'
end
cookbook_file '/tmp/MySQL-client.rpm' do
source 'MySQL-client-5.6.15-1.el6.x86_64.rpm'
end
cookbook_file '/tmp/MySQL-devel.rpm' do
source 'MySQL-devel-5.6.15-1.el6.x86_64.rpm'
end
cookbook_file '/tmp/MySQL-shared.rpm' do
source 'MySQL-shared-5.6.15-1.el6.x86_64.rpm'
end
cookbook_file '/tmp/MySQL-shared-compat.rpm' do
source 'MySQL-shared-compat-5.6.15-1.el6.x86_64.rpm'
end
インストールする
あとはrpm
からインストールするだけです。
これもdefault.rb
に書いていきます。
rpm_package 'MySQL-server' do
source '/tmp/MySQL-server.rpm'
end
rpm_package 'MySQL-client' do
source '/tmp/MySQL-client.rpm'
end
rpm_package 'MySQL-devel' do
source '/tmp/MySQL-devel.rpm'
end
rpm_package 'MySQL-shared' do
source '/tmp/MySQL-shared.rpm'
end
rpm_package 'MySQL-shared-compat' do
source '/tmp/MySQL-shared-compat.rpm'
end
実行する
華麗に実行します。
$ knife solo cook sample
で、で、できたー!(できなかったらごめんなさい)
参考サイト
- CentOS6.4にMySQL5.5をインストールするChefレシピを作った - 世界中の羊をかき集めて
- mysql-serverを入れようとするとmysql-libsとコンフリクトする件 - webネタ
- rpm_package — Chef Docs
追記:2013/12/15
以下のように、もっとすっきりと書いてみました。
レシピ
$ vi site-cookbooks/mysql/recipes/default.rb
package 'mysql-libs' do
action :remove
end
node['mysql']['rpm'].each do |rpm|
cookbook_file "/tmp/#{rpm}" do
action :create
source "#{rpm}"
end
rpm_package "#{rpm}" do
action :install
source "/tmp/#{rpm}"
end
end
rpmの設定
$ vi site-cookbooks/mysql/attributes/default.rb
default['mysql']['rpm'] = [
'MySQL-server-5.6.15-1.el6.x86_64.rpm',
'MySQL-client-5.6.15-1.el6.x86_64.rpm',
'MySQL-devel-5.6.15-1.el6.x86_64.rpm',
'MySQL-shared-5.6.15-1.el6.x86_64.rpm',
'MySQL-shared-compat-5.6.15-1.el6.x86_64.rpm'
]
Chef SoloでVagrant上にRubyをインストールする方法
ChefでVagrant上にruby
の実行環境を構築してみましたので、そのレシピを公開などしてみます。
ただ、基本的に以下の記事と同じような形になってしまいますた。。。
クックブックの内容
レシピを作成する
まずはサクッとレシピを作成しましょう。
名前はruby
にします。
$ knife cookbook create ruby -o site-cookbooks/
rbenvを準備する
ruby
をインストールするには、まずrbenv
をインストールします。
1ブロックずつ書いてcook
していけば、動きが分かってよいです。
$ vi /site-cookbooks/ruby/recipes/rbenv.rb
group 'rbenv' do
action :create
members 'vagrant'
append true
end
git '/usr/local/rbenv' do
repository 'git://github.com/sstephenson/rbenv.git'
reference 'master'
action :checkout
user "#{node.user}"
group 'rbenv'
end
directory '/usr/local/rbenv/plugins' do
action :create
owner "#{node.user}"
group 'rbenv'
mode 0755
end
template '/etc/profile.d/rbenv.sh' do
owner "#{node.user}"
group "#{node.user}"
mode 0644
end
PackageやDSLが分からなくなったら、とりあえず公式ドキュメントを見ます!
ruby-buildを準備する
次にruby-build
をインストールします。
これはgit
から持ってくるだけです。
$ vi /site-cookbooks/ruby/recipes/ruby-build.rb
git '/usr/local/rbenv/plugins/ruby-build' do
repository 'git://github.com/sstephenson/ruby-build.git'
reference 'master'
action :checkout
user "#{node.user}"
group 'rbenv'
end
インストールする
あとは上記をinstall
でインストールして、global
でバージョンを切り替えるだけです。
$ vi /site-cookbooks/ruby/recipes/install.rb
execute 'ruby install' do
not_if "source /etc/profile.d/rbenv.sh; rbenv versions | grep #{node.ruby.version}"
command "source /etc/profile.d/rbenv.sh; rbenv install #{node.ruby.version}"
action :run
end
execute 'ruby change' do
command "source /etc/profile.d/rbenv.sh; rbenv global #{node.ruby.version}; rbenv rehash"
action :run
end
default.rbから呼び出す
上記の手順を明示的に実行するため、include_recipe
を書きます。
$ vi /site-cookbooks/ruby/recipes/default.rb
include_recipe 'ruby::rbenv'
include_recipe 'ruby::ruby-build'
include_recipe 'ruby::install'
環境設定を書く
上記ファイルに#{node.user}
や#{node.ruby.version}
といった変数があると思います。
これも設定します。
$ vi /site-cookbooks/ruby/attributes/default.rb
default['user'] = 'root'
default['ruby']['version'] = '2.0.0-p353'
実行
あとはnodes/[host].json
のrun_list
に追記して、knife solo cook
すればruby
のインストールが完了します!
だいぶレシピの書き方が分かってきた……ような、気が、するだけ、ですね。。。
ファイルのパーミッションの"T"はスティッキービットというらしい
Chefでrbenv
のbash
を作成したところ、ファイルのパーミッションが以下のようになりました。
--w----r-T 1 root root 93 12月 12 11:00 2013 rbenv.sh
原因は、mode
を0644
ではなく644
とタイポしたというだけのことですが、このT
とはなんぞ? と思ったので、調べてみました。
Tはスティッキー・ビット
どうやらパーミッションには、r
やw
、x
以外にもT
やらなにやらがあるらしいのです。
T
は、スティッキービットと呼ばれ、以下のような特徴があるらしいです。
スティッキービットの最も一般的な使用法は、ディレクトリに対して使う場合であり、セットされるとディレクトリ配下のファイルのファイル名変更や削除はそのファイルの所有者、ディレクトリの所有者、スーパーユーザーのいずれかしかできなくなる。
ふむふむ。
スティッキービットの設定方法
じゃあどうやったらスティッキービットを設定するの、という話ですが、以下の方法で設定できるようです。
chmod 1777 hoge
chmod
にこんな裏要素があるなんて知りませんでした。。。