本ブログを3年やってきました。
ですが、このBloggerはでブログ記事を書くのは辛いです。。。
編集しづらいことが苦行でした。
そのため、markdownで記事が記述できるOctpressにこの度移行することにしました。
記事も気に入ったものというか、役に立つものから順に移行していきます。多分。
当面、記事を削除する予定はないですが、気が変わったら削除します。
新ブログ
http://moonstruckdrops.github.com
以上
2013-03-25
2013-02-28
[AppEngine]AppEngineでbyte配列を扱う
表題のことをするだけなんだが、苦労した。
普通に文字列をbyte配列に変換して、更に元に戻す場合だとこんな感じにやると思います。
ただ、これだとローカル環境だと問題無く使えますが、本番環境だとうまく扱えなくなります。
何故かというとAppEngineでは、Protocol Buffersを使用してるからです。
どうやら、Protocol Buffersでは、byte配列の扱いが異なるようです。
特にGoogleのサービスを扱う場合、特に注意したほうがよいでしょう。
自分は、UrlFetchサービスで困りました(文字化けが盛大に起こっていたなど)
他にもbyte配列を扱うようなサービスDatastoreサービスでも文字化けが起こるような可能性は高いでしょう。
というわけで、こんな感じでProtocol Buffersを使えばよいですね。
これで、byte配列に変換しても困ることなく扱えますね。
普通に文字列をbyte配列に変換して、更に元に戻す場合だとこんな感じにやると思います。
byte[] data = "hoge".getBytes(); String str = new String(data);
ただ、これだとローカル環境だと問題無く使えますが、本番環境だとうまく扱えなくなります。
何故かというとAppEngineでは、Protocol Buffersを使用してるからです。
どうやら、Protocol Buffersでは、byte配列の扱いが異なるようです。
特にGoogleのサービスを扱う場合、特に注意したほうがよいでしょう。
自分は、UrlFetchサービスで困りました(文字化けが盛大に起こっていたなど)
他にもbyte配列を扱うようなサービスDatastoreサービスでも文字化けが起こるような可能性は高いでしょう。
というわけで、こんな感じでProtocol Buffersを使えばよいですね。
ByteString copyFrom = ByteString.copyFromUtf8(data); byte[] byteData = copyFrom.toByteArray();
これで、byte配列に変換しても困ることなく扱えますね。
2013-02-25
[Android]APIに変更を入れた場合のビルドは更新コマンドが必要
1年ぶりにAOSPに貢献してみました。。。
▲経緯
Androidのソースコードは、ドキュメントと機能が一致していないようなことが結構あったりします。
下手をすると、ドキュメントが何も記載されていないメソッドなり機能だったりがあります。
# もしかしたら自分の英語の読解力が無いだけかもしれまんせんが。
そういうわけで、自分の拙い英語力だけどドキュメントでも書いてあげればいいんじゃねーのとか思うわけです。
# 同じように困ってるような人はいると思いますので・・・
というわけで、ドキュメントを少し書いてみた。(一部、APIも変えてみましたが)
よし、ビルドが通ればコミットするぞ・・・と息巻いてたところビルドでコケるというような事象がありました。
▲解決
エラーログにapiを更新するようなコマンド叩いてみるといいよと出てますので実行します。
$make update-api
それから再度ビルドを実施します。
$make -j4
一応、以下にエラーログを記載しておきます(抜粋)
Checking API: checkapi-current Compiling SDK Stubs: out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes.jar out/target/common/obj/PACKAGING/public_api.txt:11256: error 21: Method ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1) You can add "@hide" javadoc comments to the methods, etc. listed in the errors above. 2) You can update current.txt by executing the following command: make update-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** make: *** [out/target/common/obj/PACKAGING/checkapi-current-timestamp] Error 38 make: *** Waiting for unfinished jobs.... 'out/target/common/obj/APPS/Settings_intermediates/classes.dex' as 'classes.dex'... out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/java/security/cert/PKIXBuilderParameters.java:5: ?x??:[unchecked] ???????ϊ??ł?
2013-01-27
[Linux]CentOSの開発環境を見なおしてた。。。
先月から色々ドタバタだった。
ようやく(?)少し落ち着いたかもしれない。。。
落ち着いたかもしれないところで開発に使用しているCentOSの環境を見なおしてみた。。。
なんで見なおしてみたかったかというと、
「/usr/localにインストールしているアプリケーション類のパッケージ管理をrpmにしたかった。」
ただ、それだけなんですけど。乱立しているのは避けたいところ(公式だと古いものが多かったりで入れなおしたりとか)
とは言ったものの、できないものもあるわけで・・・(eclipseとかandroidとか)
▲エディタ
ViとかVimは最低限のレベルでしか使えない人なのでEmacsが欲しいところ。
とはいえ、パッケージ管理があったりしてる24.1以上が欲しい。(単につかうだけなら公式から23.3だっけを入れればいいのですが)
rpmビルドしたEmacsをインストールします。
ビルド方法
http://moonstruckdrops.blogspot.jp/2012/12/linuxrpmspecemacs.html
▲bash_completion
こいつないと、コマンドの補完周りが貧弱になるので必須。
という訳でEPELからインストールしましょう。
$wget http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$rpm -Uvh epel-release-6-8.noarch
$yum --enablerepo=epel check-update
$yum --enablerepo=epel install bash_completion
EPEL
http://fedoraproject.org/wiki/EPEL
▲ターミナル
GNU Screenだと分割周りがつらかったりするので、tmuxを入れます。
というわけで、配布してるRepoforge(Rpmforge)をインストールしてからtmuxをインストールします
$wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$rpm -Uvh rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$yum --enablerepo=rpmforge check-update
$yum --enablerepo=rpmforge install tmux
▲ブラウザ
Firefoxで一応、実用上十分なんだけど、JSの実装とか細かい違いとかで新しいものがやっぱり欲しいところ。
というわけで、Chromeが欲しいですね。
Google RPM Packages
http://www.google.com/linuxrepositories/
一応、ThirdPartyを使えばFirefox18も入れれることができます。(Remiリポジトリ)
$rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
$yum --enablerepo=remi list firefox
$yum --enablerepo=remi update firefox
▲Java
Oracleからパッケージをダウンロードしてインストール
eclipseとandroidはどうにもならないので諦めましょう。
(/usr/local/shareにいれて、シンボリックリンクを/usr/local/binにつけるとかで対処かな)
▲Ruby
rbenv+ruby-buildを組み合わせてやればいいでしょう。
欲しいライブラリなどはgemで一発インストール。
rbenv
https://github.com/sstephenson/rbenv
ruby-build
https://github.com/sstephenson/ruby-build
※インストール方法とか設定は今度書くかもしれない
▲Python
公式が2.6と古いの2.7系にしたい(今はアーリーアダプタな方たちの3系とかもそのうち使うかも)
rpmを作成してインストールしましょう
▲DB
Postgeresqlを使うこともあるでしょう。。。
rpmのサイトからリポジトリ先をダウンロードしてインストールしてからyumでインストール
PostgreSQL RPM Building Project
http://yum.postgresql.org/repopackages.php
MySQLを使うこともあるでしょう。。。
$yum install mysql-server
新しいものが欲しい場合、ミラーからrpmを個別にダウンロードして
インストールすればいいかもしれないですね。
MySQL mirrorリスト
http://dev.mysql.com/downloads/mirrors.html
▲バージョン管理
流行りのGitを使いたいところ
公式のバージョンは古杉なので、自分でrpmを作成してインストールしましょう。
とは言え、Subversionを使ってるところも多いので一応インストールします。(git-svnでも使いますからね)
$yum install subversion
git.spec
gitweb.conf.in
他にもなんか色々あったかもしれないけど、こんなところかね。
※GCCとか暗黙的に使うようなものは、書いてません。
ようやく(?)少し落ち着いたかもしれない。。。
落ち着いたかもしれないところで開発に使用しているCentOSの環境を見なおしてみた。。。
なんで見なおしてみたかったかというと、
「/usr/localにインストールしているアプリケーション類のパッケージ管理をrpmにしたかった。」
ただ、それだけなんですけど。乱立しているのは避けたいところ(公式だと古いものが多かったりで入れなおしたりとか)
とは言ったものの、できないものもあるわけで・・・(eclipseとかandroidとか)
▲エディタ
ViとかVimは最低限のレベルでしか使えない人なのでEmacsが欲しいところ。
とはいえ、パッケージ管理があったりしてる24.1以上が欲しい。(単につかうだけなら公式から23.3だっけを入れればいいのですが)
rpmビルドしたEmacsをインストールします。
ビルド方法
http://moonstruckdrops.blogspot.jp/2012/12/linuxrpmspecemacs.html
▲bash_completion
こいつないと、コマンドの補完周りが貧弱になるので必須。
という訳でEPELからインストールしましょう。
$wget http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$rpm -Uvh epel-release-6-8.noarch
$yum --enablerepo=epel check-update
$yum --enablerepo=epel install bash_completion
EPEL
http://fedoraproject.org/wiki/EPEL
▲ターミナル
GNU Screenだと分割周りがつらかったりするので、tmuxを入れます。
というわけで、配布してるRepoforge(Rpmforge)をインストールしてからtmuxをインストールします
$wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$rpm -Uvh rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$yum --enablerepo=rpmforge check-update
$yum --enablerepo=rpmforge install tmux
▲ブラウザ
Firefoxで一応、実用上十分なんだけど、JSの実装とか細かい違いとかで新しいものがやっぱり欲しいところ。
というわけで、Chromeが欲しいですね。
Google RPM Packages
http://www.google.com/linuxrepositories/
一応、ThirdPartyを使えばFirefox18も入れれることができます。(Remiリポジトリ)
$rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
$yum --enablerepo=remi list firefox
$yum --enablerepo=remi update firefox
▲Java
Oracleからパッケージをダウンロードしてインストール
eclipseとandroidはどうにもならないので諦めましょう。
(/usr/local/shareにいれて、シンボリックリンクを/usr/local/binにつけるとかで対処かな)
▲Ruby
rbenv+ruby-buildを組み合わせてやればいいでしょう。
欲しいライブラリなどはgemで一発インストール。
rbenv
https://github.com/sstephenson/rbenv
ruby-build
https://github.com/sstephenson/ruby-build
※インストール方法とか設定は今度書くかもしれない
▲Python
公式が2.6と古いの2.7系にしたい(今はアーリーアダプタな方たちの3系とかもそのうち使うかも)
rpmを作成してインストールしましょう
%define binsuffix 2.7
%define libvers 2.7
# 一括置換で修正
%define libdirname lib
Summary: An interpreted, interactive, object-oriented programming language.
Name: python27
Version: 2.7.2
Release: %{?dist}.3
License: PSF
Group: Development/Languages
Source: Python-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: gcc make expat-devel db4-devel gdbm-devel sqlite-devel readline-devel zlib-devel bzip2-devel openssl-devel
AutoReq: no
Vendor: kurobara
Packager: kurobara
%description
Python is an interpreted, interactive, object-oriented programming
language. It incorporates modules, exceptions, dynamic typing, very high
level dynamic data types, and classes. Python combines remarkable power
with very clear syntax. It has interfaces to many system calls and
libraries, as well as to various window systems, and is extensible in C or
C++. It is also usable as an extension language for applications that need
a programmable interface. Finally, Python is portable: it runs on many
brands of UNIX, on PCs under Windows, MS-DOS, and OS/2, and on the
Mac.
%package devel
Summary: The libraries and header files needed for Python extension development.
Requires: %{name} = %{version}-%{release}
Group: Development/Libraries
%description devel
The Python programming language's interpreter can be extended with
dynamically loaded extensions and can be embedded in other programs.
This package contains the header files and libraries needed to do
these types of tasks.
Install python-devel if you want to develop Python extensions. The
python package will also need to be installed. You'll probably also
want to install the python-docs package, which contains Python
documentation.
### tkinterが有効時にコメントアウトを外す
#%package tkinter
#Summary: A graphical user interface for the Python scripting language.
#Group: Development/Languages
#Requires: %{name} = %{version}-%{release}
#%description tkinter
#The Tkinter (Tk interface) program is an graphical user interface for
#the Python scripting language.
#
#You should install the tkinter package if youd like to use a graphical
#user interface for Python programming.
%package tools
Summary: A collection of development tools included with Python.
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
%description tools
The Python package includes several development tools that are used
to build python programs. This package contains a selection of those
tools, including the IDLE Python IDE.
Install python-tools if you want to use these tools to develop
Python programs. You will also need to install the python and
tkinter packages.
%prep
%setup -n Python-%{version}
### BUILD
%build
%configure \
--enable-unicode=ucs4 \
--with-signal-module \
--with-threads \
--enable-shared \
--with-pymalloc \
--enable-ipv6 \
--prefix=%{_prefix}
%{__make} %{?_smp_mflags}
##########
# INSTALL
##########
%install
# set the install path
echo '[install_scripts]' >setup.cfg
echo 'install_dir='"${RPM_BUILD_ROOT}%{_prefix}/bin" >>setup.cfg
[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/lib-dynload
#%{__make} prefix=$RPM_BUILD_ROOT%{__prefix} altinstall
%{__make} altinstall DESTDIR="%{buildroot}"
### REPLACE PATH IN PYDOC
cd $RPM_BUILD_ROOT%{_prefix}/bin
mv pydoc pydoc.old
sed 's|#!.*|#!%{_prefix}/bin/python'%{binsuffix}'|' pydoc.old >pydoc
chmod 755 pydoc
rm -f pydoc.old
sed -i -e 's|#!.*|#!%{_prefix}/bin/python'%{binsuffix}'|' python%{libvers}-config
### add the binsuffix
cd $RPM_BUILD_ROOT%{_prefix}/bin;
for file in 2to3 pydoc python-config idle smtpd.py; do
[ -f "$file" ] && mv "$file" "$file"%{binsuffix};
done;
# Fix permissions
# 64bit
#chmod 644 $RPM_BUILD_ROOT%{_prefix}/%{libdirname}64/libpython%{libvers}*
# 32bit
chmod 644 $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/libpython%{libvers}*
########
# Tools
cd $RPM_BUILD_DIR/Python-%{version}
cp -a Tools $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}
### Makefileのインストール
cd $RPM_BUILD_DIR/Python-%{version}
mkdir -p $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/config
#chmod 644 $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/config
%{__install} -p -m0644 Makefile $RPM_BUILD_ROOT%{_prefix}/%{libdirname}/python%{libvers}/config
# MAKE FILE LISTS
rm -f mainpkg.files
find "$RPM_BUILD_ROOT""%{_prefix}"/%{libdirname}/python%{libvers} -type f |
sed "s|^${RPM_BUILD_ROOT}|/|" | grep -v -e '_tkinter.so$' >mainpkg.files
find "$RPM_BUILD_ROOT""%{_prefix}"/bin -type f -o -type l |
sed "s|^${RPM_BUILD_ROOT}|/|" |
grep -v -e '/bin/2to3%{binsuffix}$' |
grep -v -e '/bin/pydoc%{binsuffix}$' |
grep -v -e '/bin/smtpd.py%{binsuffix}$' |
grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files
echo %{_prefix}/include/python%{libvers}/pyconfig.h >> mainpkg.files
rm -f tools.files
echo "%{_prefix}"/%{libdirname}/python%{libvers}/Tools >>tools.files
echo "%{_prefix}"/%{libdirname}/python%{libvers}/lib2to3/tests >>tools.files
echo "%{_prefix}"/bin/2to3%{binsuffix} >>tools.files
echo "%{_prefix}"/bin/pydoc%{binsuffix} >>tools.files
echo "%{_prefix}"/bin/smtpd.py%{binsuffix} >>tools.files
echo "%{_prefix}"/bin/idle%{binsuffix} >>tools.files
# fix the #! line in installed files
find "$RPM_BUILD_ROOT" -type f -print0 |
xargs -0 grep -l /usr/local/bin/python | while read file
do
FIXFILE="$file"
sed 's|^#!.*python|#!%{_prefix}/bin/python'"%{binsuffix}"'|' \
"$FIXFILE" >/tmp/fix-python-path.$$
cat /tmp/fix-python-path.$$ >"$FIXFILE"
rm -f /tmp/fix-python-path.$$
done
########
# CLEAN
########
%clean
[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT
rm -f mainpkg.files tools.files
########
# FILES
########
%files -f mainpkg.files
%defattr(-,root,root)
%doc Misc/README Misc/cheatsheet Misc/Porting
%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS
# OMG I'm a Lazy hack.
%{_prefix}/lib/python2.7/lib-dynload/
# 64bit
#%{_prefix}/lib64/python2.7/lib-dynload/
#%{_prefix}/lib64/pkgconfig/python-2.7.pc
# 32bit
%{_prefix}/lib/python2.7/lib-dynload/
%{_prefix}/lib/pkgconfig/python-2.7.pc
%attr(755,root,root) %dir %{_prefix}/include/python%{libvers}
%attr(755,root,root) %dir %{_prefix}/lib/python%{libvers}/
%attr(755,root,root) %dir %{_prefix}/%{libdirname}/python%{libvers}/
### ライブラリ
# 64bit
#%{_prefix}/%{libdirname}64/libpython*
# 32bit
%{_prefix}/%{libdirname}/libpython*
%files devel
%defattr(-,root,root)
%{_prefix}/include/python%{libvers}/*.h
# 64bit
#%{_prefix}/%{libdirname}64/python%{libvers}/config
# 32bit
%{_prefix}/%{libdirname}/python%{libvers}/config
%files -f tools.files tools
%defattr(-,root,root)
### tkinterが有効時にコメントアウトを外す
#%files tkinter
#%defattr(-,root,root)
#%{__prefix}/%{libdirname}/python%{libvers}/lib-tk
#%{__prefix}/%{libdirname}64/python%{libvers}/lib-dynload/_tkinter.so*
▲DB
Postgeresqlを使うこともあるでしょう。。。
rpmのサイトからリポジトリ先をダウンロードしてインストールしてからyumでインストール
PostgreSQL RPM Building Project
http://yum.postgresql.org/repopackages.php
MySQLを使うこともあるでしょう。。。
$yum install mysql-server
新しいものが欲しい場合、ミラーからrpmを個別にダウンロードして
インストールすればいいかもしれないですね。
MySQL mirrorリスト
http://dev.mysql.com/downloads/mirrors.html
▲バージョン管理
流行りのGitを使いたいところ
公式のバージョンは古杉なので、自分でrpmを作成してインストールしましょう。
とは言え、Subversionを使ってるところも多いので一応インストールします。(git-svnでも使いますからね)
$yum install subversion
git.spec
%define perl_vendorlib %(eval "`%{__perl} -V:installvendorlib`"; echo $installvendorlib)
%define perl_vendorarch %(eval "`%{__perl} -V:installvendorarch`"; echo $installvendorarch)
%define desktop_vendor kurobara
Summary: Git core and tools
Name: git
Version: 1.8.1.1
Release: %{?dist}.3
License: GPL
Group: Development/Tools
URL: http://git-scm.com/
Packager: kurobara
Vendor: kurobara
Source0: https://git-core.googlecode.com/files/git-%{version}.tar.gz
Source1: gitweb.conf.in
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: asciidoc > 6.0.3
BuildRequires: curl-devel >= 7.9
BuildRequires: desktop-file-utils
BuildRequires: expat-devel
BuildRequires: gettext
BuildRequires: emacs
BuildRequires: openssl-devel
BuildRequires: perl(ExtUtils::MakeMaker)
BuildRequires: xmlto
BuildRequires: zlib-devel >= 1.2
Requires: less
Requires: openssh-clients
Requires: perl-Git = %{version}-%{release}
Requires: rsync
Requires: zlib >= 1.2
Obsoletes: git-core <= %{version}-%{release}
Provides: git-core = %{version}-%{release}
%description
GIT comes in two layers. The bottom layer is merely an extremely fast
and flexible filesystem-based database designed to store directory trees
with regard to their history. The top layer is a SCM-like tool which
enables human beings to work with the database in a manner to a degree
similar to other SCM tools (like CVS, BitKeeper or Monotone).
%package all
Summary: Meta-package to pull in all git tools
Group: Development/Tools
Requires: emacs-git = %{version}-%{release}
Requires: git = %{version}-%{release}
Requires: git-arch = %{version}-%{release}
Requires: git-cvs = %{version}-%{release}
Requires: git-email = %{version}-%{release}
Requires: git-gui = %{version}-%{release}
Requires: git-svn = %{version}-%{release}
Requires: gitk = %{version}-%{release}
Requires: perl-Git = %{version}-%{release}
Obsoletes: git <= 1.5.4.3
%description all
Git is a fast, scalable, distributed revision control system with an
unusually rich command set that provides both high-level operations
and full access to internals.
This is a dummy package which brings in all subpackages.
%package arch
Summary: Git tools for importing Arch repositories
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
%description arch
Git tools for importing Arch repositories.
%package cvs
Summary: Git tools for importing CVS repositories
Group: Development/Tools
Requires: cvs
Requires: cvsps
Requires: %{name} = %{version}-%{release}
%description cvs
Git tools for importing CVS repositories.
%package daemon
Summary: Git protocol daemon
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: xinetd
%description daemon
The git daemon for supporting git:// access to git repositories
%package email
Summary: Git tools for sending email
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: perl-Git = %{version}
Requires: perl(Authen::SASL::Perl)
Requires: perl(Email::Valid)
Requires: perl(Mail::Address)
Requires: perl(Net::Domain)
Requires: perl(Net::SMTP::SSL)
Requires: perl(Sys::Hostname)
%description email
Git tools for sending email.
%package gui
Summary: Graphical frontend to git
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: tk >= 8.4
Requires: gitk = %{version}-%{release}
%description gui
Graphical frontend to git.
%package svn
Summary: Git tools for importing Subversion repositories
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: perl(Error)
Requires: perl(Term::ReadKey)
Requires: subversion
%description svn
Git tools for importing Subversion repositories.
%package -n emacs-git
Summary: Git version control system support for Emacs
Group: Applications/Editors
Requires: %{name} = %{version}-%{release}
Requires: emacs-common
%description -n emacs-git
%{summary}.
%package -n gitk
Summary: Git revision tree visualiser
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: tk >= 8.4
%description -n gitk
Git revision tree visualiser.
%package -n gitweb
Summary: Simple web interface to git repositories
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
%description -n gitweb
Simple web interface to track changes in git repositories
%package -n perl-Git
Summary: Perl module that implements Git bindings
Group: Applications/CPAN
### 以下の理由でコメントアウト
### 動作に必要という点ではgitに依存する
### 設定した場合にgitそのものがインストールできなくなる
#Requires: %{name} = %{version}-%{release}
%description -n perl-Git
Git is a Perl module that implements Git bindings.
%prep
%setup
%{__cat} <config.mak
V = 1
CFLAGS = %{optflags}
BLK_SHA1 = 1
NEEDS_CRYPTO_WITH_SSL = 1
NO_PYTHON = 1
ETC_GITCONFIG = %{_sysconfdir}/gitconfig
DESTDIR = %{buildroot}
INSTALL = install -p
GITWEB_PROJECTROOT = %{_localstatedir}/lib/git
htmldir = %{_docdir}/%{name}-%{version}
prefix = %{_prefix}
INSTALLDIRS = vendor
mandir = %{_mandir}
WITH_OWN_SUBPROCESS_PY = YesPlease
ASCIIDOC_EXTRA = --unsafe
EOF
### gitdaemonの設定
### gitdaemon用のxファイルを生成
%{__cat} <git.xinetd
# default: off
# description: The git daemon allows git repositories to be exported using \
# the git:// protocol.
service git
{
disable = yes
# git is in /etc/services only on RHEL5+
#type = UNLISTED
#port = 9418
socket_type = stream
wait = no
user = nobody
server = %{_libexecdir}/git-core/git-daemon
server_args = --base-path=%{_localstatedir}/lib/git --export-all --user-path=public_git --syslog --inetd --verbose
log_on_failure += USERID
# xinetd does not enable IPv6 by default
# flags = IPv6
}
EOF
### gitguiの設定
### gitgui.desktopの生成
%{__cat} <git-gui.desktop
[Desktop Entry]
Name=Git GUI
GenericName=Git GUI
Comment=A graphical interface to Git
Exec=git gui
Icon=%{_datadir}/git-gui/lib/git-gui.ico
Terminal=false
Type=Application
Categories=Development;
EOF
### gitwebの設定
### gitweb.httpdの生成
%{__cat} <gitweb/gitweb.httpd
Alias /git %{_datadir}/gitweb
Options +ExecCGI
AddHandler cgi-script .cgi
DirectoryIndex gitweb.cgi
EOF
### gitweb.confの生成
%{__sed} -e "s|@PROJECTROOT@|%{_localstatedir}/lib/git|g" %{SOURCE1} >gitweb.conf
### RPMインストール設定
### インストール時に設定される不要な依存を削除する
cat << \EOF > %{name}-req
#!/bin/sh
%{__perl_requires} $* |\
sed -e '/perl(packed-refs)/d'
EOF
%global __perl_requires %{_builddir}/%{name}-%{version}/%{name}-req
chmod +x %{__perl_requires}
%build
%{__make} %{?_smp_mflags} all
# bah, DocBook validation errors
%{__perl} -pi -e 's|^XMLTO_EXTRA =\s*$|XMLTO_EXTRA = --skip-validation \n|;' Documentation/Makefile
%{__make} %{?_smp_mflags} doc
## Perl preparation
cd perl
%{__perl} Makefile.PL DESTDIR="%{buildroot}" PREFIX="%{_prefix}" INSTALLDIRS=%{perl_vendorlib}
%{__make} %{?_smp_mflags}
cd -
# Remove shebang from bash-completion script
sed -i '/^#!bash/,+1 d' contrib/completion/git-completion.bash
%install
### 初期化の実施
%{__rm} -rf %{buildroot}
### git installation
%{__make} install install-doc DESTDIR="%{buildroot}"
%{__make} -C contrib/emacs install emacsdir="%{buildroot}%{_datadir}/emacs/site-lisp"
for elc in %{buildroot}%{_datadir}/emacs/site-lisp/*.elc; do
%{__install} -p -m0644 contrib/emacs/$(basename $elc .elc).el %{buildroot}%{_datadir}/emacs/site-lisp/
done
#%{__install} -Dp -m0644 %{SOURCE1} %{buildroot}%{_datadir}/emacs/site-lisp/site-start.d/git-init.el
### perl-Git installation
### perlモジュールのインストールでエラーが出ていたので個別にインストールする
%{__install} -p -m0644 perl/blib/lib/Git.pm %{buildroot}/usr/share/perl5/Git.pm
%{__install} -p -m0644 perl/blib/lib/Git/I18N.pm %{buildroot}/usr/share/perl5/Git/I18N.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Editor.pm %{buildroot}/usr/share/perl5/Git/SVN/Editor.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Fetcher.pm %{buildroot}/usr/share/perl5/Git/SVN/Fetcher.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Memoize/YAML.pm %{buildroot}/usr/share/perl5/Git/SVN/Memoize/YAML.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Prompt.pm %{buildroot}/usr/share/perl5/Git/SVN/Prompt.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Ra.pm %{buildroot}/usr/share/perl5/Git/SVN/Ra.pm
%{__install} -p -m0644 perl/blib/lib/Git/IndexInfo.pm %{buildroot}/usr/share/perl5/Git/IndexInfo.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN.pm %{buildroot}/usr/share/perl5/Git/SVN.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/GlobSpec.pm %{buildroot}/usr/share/perl5/Git/SVN/GlobSpec.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Log.pm %{buildroot}/usr/share/perl5/Git/SVN/Log.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Migration.pm %{buildroot}/usr/share/perl5/Git/SVN/Migration.pm
%{__install} -p -m0644 perl/blib/lib/Git/SVN/Utils.pm %{buildroot}/usr/share/perl5/Git/SVN/Utils.pm
### gitweb installation
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/www/git/static/
%{__install} -p -m0755 gitweb/gitweb.cgi %{buildroot}%{_localstatedir}/www/git/
%{__install} -p -m0755 gitweb/gitweb.perl %{buildroot}%{_localstatedir}/www/git/
%{__cp} -av gitweb/static/* %{buildroot}%{_localstatedir}/www/git/static/
%{__install} -Dp -m0644 gitweb/gitweb.httpd %{buildroot}%{_sysconfdir}/httpd/conf.d/git.conf
%{__install} -Dp -m0644 gitweb.conf %{buildroot}%{_sysconfdir}/gitweb.conf
### git-daemon installation
%{__install} -d -m0755 %{buildroot}%{_localstatedir}/lib/git/
%{__install} -d -m0755 %{buildroot}%{_sysconfdir}/xinetd.d/
%{__install} -Dp -m0644 git.xinetd %{buildroot}%{_sysconfdir}/xinetd.d/git
### contrib installation
%{__install} -Dp -m0644 contrib/completion/git-completion.bash %{buildroot}%{_sysconfdir}/bash_completion.d/git
# Move contrib/hooks out of %%docdir and make them executable
%{__install} -d -m0755 %{buildroot}%{_datadir}/git-core/contrib/
%{__mv} -v contrib/hooks %{buildroot}%{_datadir}/git-core/contrib
chmod +x %{buildroot}%{_datadir}/git-core/contrib/hooks/*
pushd contrib > /dev/null
ln -s ../../../git-core/contrib/hooks
popd > /dev/null
desktop-file-install \
--vendor %{desktop_vendor} \
--dir=%{buildroot}%{_datadir}/applications \
git-gui.desktop
### Quiet some rpmlint complaints
chmod -R g-w %{buildroot}
find %{buildroot} -name git-mergetool--lib | xargs chmod a-x
rm -f {Documentation/technical,contrib/emacs}/.gitignore
chmod a-x Documentation/technical/api-index.sh
find contrib -type f | xargs chmod -x
### Clean up buildroot
find %{buildroot}%{_bindir} -type f -exec %{__perl} -pi -e 's|^%{buildroot}||' {} \;
%{__rm} -rf %{buildroot}%{perl_archlib} %{buildroot}%{perl_vendorarch} %{buildroot}%{_datadir}/locale/*
%clean
%{__rm} -rf %{buildroot}
%files
%defattr(-, root, root, 0755)
%doc COPYING Documentation/*.txt README
%doc %{_mandir}/man1/*.1*
%doc %{_mandir}/man5/*.5*
%doc %{_mandir}/man7/*.7*
%config %{_sysconfdir}/bash_completion.d/
%{_datadir}/emacs/site-lisp/git*
%{_bindir}/git
%{_bindir}/git-*
%{_datadir}/git-core/
%{_libexecdir}/git-core/
%exclude %{_libexecdir}/git-core/git-citool
%exclude %{_libexecdir}/git-core/git-cvsexportcommit
%exclude %{_libexecdir}/git-core/git-cvsimport
%exclude %{_libexecdir}/git-core/git-cvsserver
%exclude %{_libexecdir}/git-core/git-daemon
%exclude %{_libexecdir}/git-core/git-gui
%exclude %{_libexecdir}/git-core/git-gui--askpass
%exclude %{_libexecdir}/git-core/git-send-email
%exclude %{_libexecdir}/git-core/git-svn
%files all
%defattr(-, root, root, 0755)
%files arch
%defattr(-, root, root, 0755)
%{_libexecdir}/git-core/git-archimport
%files cvs
%defattr(-, root, root, 0755)
%{_bindir}/git-cvsserver
%{_libexecdir}/git-core/git-cvsexportcommit
%{_libexecdir}/git-core/git-cvsimport
%{_libexecdir}/git-core/git-cvsserver
%files daemon
%defattr(-, root, root, 0755)
%doc Documentation/*daemon*.txt
%config(noreplace)%{_sysconfdir}/xinetd.d/git
%{_libexecdir}/git-core/git-daemon
%{_localstatedir}/lib/git/
%files email
%defattr(-, root, root, 0755)
%{_libexecdir}/git-core/git-send-email
%files gui
%defattr(-, root, root, 0755)
%{_datadir}/applications/%{desktop_vendor}-git-gui.desktop
%{_datadir}/git-gui/
%{_libexecdir}/git-core/git-citool
%{_libexecdir}/git-core/git-gui
%{_libexecdir}/git-core/git-gui--askpass
%files svn
%defattr(-, root, root, 0755)
%{_libexecdir}/git-core/git-svn
%files -n gitk
%defattr(-,root,root)
%doc Documentation/*gitk*.txt
%{_bindir}/gitk
%{_datadir}/gitk/
%files -n gitweb
%defattr(-, root, root, 0755)
%doc gitweb/GITWEB-BUILD-OPTIONS gitweb/INSTALL gitweb/README
%config(noreplace) %{_sysconfdir}/gitweb.conf
%config(noreplace) %{_sysconfdir}/httpd/conf.d/git.conf
%{_datadir}/gitweb/
%{_localstatedir}/www/git/*.cgi
%{_localstatedir}/www/git/*.perl
%{_localstatedir}/www/git/static/*.css
%{_localstatedir}/www/git/static/*.png
%{_localstatedir}/www/git/static/*.js
%{_localstatedir}/www/git/static/js/**
%files -n perl-Git
%defattr(-, root, root, 0755)
%doc %{_mandir}/man3/Git.3pm*
%doc %{_mandir}/man3/Git::I18N.3pm*
%doc %{_mandir}/man3/Git::SVN::Editor.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Fetcher.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Memoize::YAML.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Prompt.3pm.gz
%doc %{_mandir}/man3/Git::SVN::Ra.3pm.gz
# perlモジュールのインストールでエラーが出るので個別にパッケージするファイルを指定
/usr/share/perl5/Git.pm
/usr/share/perl5/Git/I18N.pm
/usr/share/perl5/Git/SVN/Editor.pm
/usr/share/perl5/Git/SVN/Fetcher.pm
/usr/share/perl5/Git/SVN/Memoize/YAML.pm
/usr/share/perl5/Git/SVN/Prompt.pm
/usr/share/perl5/Git/SVN/Ra.pm
# git-1.8.1.1で追加になったモジュール
%doc %{_mandir}/man3/Git::SVN::Utils.3pm.gz
/usr/share/perl5/Git/IndexInfo.pm
/usr/share/perl5/Git/SVN.pm
/usr/share/perl5/Git/SVN/GlobSpec.pm
/usr/share/perl5/Git/SVN/Log.pm
/usr/share/perl5/Git/SVN/Migration.pm
/usr/share/perl5/Git/SVN/Utils.pm
gitweb.conf.in
# The gitweb config file is a fragment of perl code. You can set variables
# using "our $variable = value"; text from "#" character until the end of a
# line is ignored. See perlsyn(1) man page for details.
#
# See /usr/share/doc/gitweb-*/README and /usr/share/doc/gitweb-*/INSTALL for
# more details and available configuration variables.
# Set the path to git projects. This is an absolute filesystem path which will
# be prepended to the project path.
#our $projectroot = "@PROJECTROOT@";
# Set the list of git base URLs used for URL to where fetch project from, i.e.
# the full URL is "$git_base_url/$project". By default this is empty
#our @git_base_url_list = qw(git://git.example.com
# ssh://git.example.com@PROJECTROOT@);
# Enable the 'blame' blob view, showing the last commit that modified
# each line in the file. This can be very CPU-intensive. Disabled by default
#$feature{'blame'}{'default'} = [1];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.blame = 0|1;
#$feature{'blame'}{'override'} = 1;
# Disable the 'snapshot' link, providing a compressed archive of any tree. This
# can potentially generate high traffic if you have large project. Enabled for
# .tar.gz snapshots by default.
#
# Value is a list of formats defined in %known_snapshot_formats that you wish
# to offer.
#$feature{'snapshot'}{'default'} = [];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.snapshot = tbz2,zip; (use "none" to disable)
#$feature{'snapshot'}{'override'} = 1;
# Disable grep search, which will list the files in currently selected tree
# containing the given string. This can be potentially CPU-intensive, of
# course. Enabled by default.
#$feature{'grep'}{'default'} = [0];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.grep = 0|1;
#$feature{'grep'}{'override'} = 1;
# Disable the pickaxe search, which will list the commits that modified a given
# string in a file. This can be practical and quite faster alternative to
# 'blame', but still potentially CPU-intensive. Enabled by default.
#$feature{'pickaxe'}{'default'} = [0];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.pickaxe = 0|1;
#$feature{'pickaxe'}{'override'} = 1;
他にもなんか色々あったかもしれないけど、こんなところかね。
※GCCとか暗黙的に使うようなものは、書いてません。
2013-01-21
[Ruby]Rubyのチートコード(リスト編)
書いてみた。
流行りはRSpecだけど、最近購入してみたRubyMineの設定を煮詰めたり、使いやすさとかを確認してみたかったからminitestでコードを書いた。
ついでにGroovyでも同じコードを書いてみた。
RubyのほうがGroovyよりも書きやすいや。。。
テストコードを書くときぐらいしか使いそうもないな
流行りはRSpecだけど、最近購入してみたRubyMineの設定を煮詰めたり、使いやすさとかを確認してみたかったからminitestでコードを書いた。
ついでにGroovyでも同じコードを書いてみた。
class CheatCode < Test::Unit::TestCase
# 各テストメソッドが呼ばれる前に実行する前処理
def setup
end
# 各テストメソッドが呼ばれた後に実行する後処理
def teardown
end
=begin
配列の初期化
初期要素を代入して初期化する
=end
def test_array_initial
ll = [11,12,13,14]
expected = [11,12,13,14]
assert_equal(expected,ll,"ll => [11, 12, 15, 13, 14] ")
end
=begin
配列の初期化
Array.newを使用して初期化する
=end
def test_array_initial_2
ll = Array.new([11,12,13,14])
expected = [11,12,13,14]
assert_equal(expected,ll,"ll => [11, 12, 13, 14] ")
end
=begin
配列の要素数を指定して初期化
=end
def test_array_initial_3
ll = Array.new(4)
ll[0] = 11
ll[1] = 12
ll[2] = 13
ll[3] = 14
expected = [11,12,13,14]
assert_equal(expected,ll,"ll => [11, 12, 13, 14] ")
end
=begin
長さ3で各要素を[11,12,13,14]で初期化した配列を生成する
=end
def test_array_initial_4
ll = Array.new(3,[11,12,13,14])
expected = [[11,12,13,14], [11,12,13,14], [11,12,13,14]]
assert_equal(expected,ll,"ll => [[11,12,13,14], [11,12,13,14], [11,12,13,14]]")
end
=begin
for-each文
valueは配列の要素を順番に取り出す
=end
def test_each
ll = [11,12,13,14]
expected_1 = 12
expected_2 = [11,12,13,14]
# あまりよくないテスト
# valueが12の時にアサーションを実施
ll.each do |value|
if(value == 12)
assert_equal(expected_1,value,"Value is 12")
end
end
# for-eachを実施しても配列に変化無しであることを確認する
assert_equal(expected_2,ll,"ll => [11,12,13,14]")
end
=begin
引数の値が配列かどうかを調べる
配列以外を設定するとnilが返ってくるので、nilではないことでチェックができる
=end
def test_try_convert
expected = [11,12,13,14]
assert_equal(expected,Array.try_convert([11,12,13,14]),"Array.try_convert([11,12,13,14]) => [11,12,13,14]")
assert_nil(Array.try_convert("11"),"Array.try_convert(\"11\") => nil")
end
=begin
配列の平滑化をする
配列がネストしているので平滑化された値が取得できる
配列がネストしていない場合は何も実施されない
=end
def test_add_array_flaten
ll = [11,12,13,14,[15,16]]
expected = [11,12,13,14,15,16]
array = ll.flatten
assert_equal(expected,array,"ll => [11, 12, 13, 14, 15, 16]")
assert_equal(expected,array.flatten,"array => [11,12,13,14,15,16]")
end
=begin
要素の平滑化をする
破壊的な平滑化をする
=end
def test_add_array_break_flaten
ll = [11,12,13,14,[15,16]]
expected = [11,12,13,14,15,16]
assert_equal(expected,ll.flatten!,"ll.flatten? => [11, 12, 13, 14, 15, 16]")
end
=begin
要素の平滑化をする
破壊的な平滑化ですでに平滑化済みの場合、nilが返る
=end
def test_add_array_break_flaten_2
ll = [11,12,13,14,15,16]
assert_nil(ll.flatten!,"ll.flatten? => nil")
end
=begin
配列の末尾を取得する
popメソッドと違って末尾の要素は変更されない
取得要素数を指定した場合、指定した要素数分末尾から取得する
要素数が配列の長さよりも大きい場合は全要素を取得する
配列要素が空の場合、nilを返す
=end
def test_last
ll = [11,12,13,14]
expected_1 = 14
expected_2 = [13,14]
expected_3 = [11,12,13,14]
assert_equal(expected_1,ll.last,"ll.last => 14 / ll => [11,12,13,14]")
assert_equal(expected_1,ll.last,"ll.last => 14 / ll => [11,12,13,14]")
assert_equal(expected_1,ll[-1],"ll[-1] => 14")
assert_equal(expected_2,ll.last(2),"ll.last(2) => [13,14]")
assert_equal(expected_3,ll.last(5),"ll.last(2) => [11,12,13,14]")
ll.clear
assert_nil(ll.last,"ll.last => nil / ll => []")
end
=begin
配列を初期化する
===========Groovy===========
def ll = [11,12,13,14]
ll = []
assert ll.size() == 0
============================
=end
def test_list_clear
ll = [11,12,13,14]
expected = true
ll.clear
assert_equal(expected,ll.empty?,"ll.empty? is true / ll => []")
end
=begin
引数に指定した要素と等しい要素のうち最初の位置を取得する
===========Groovy===========
def ll = [11,12,13,14]
assert ll.findIndexOf { it > 12 } == 2
============================
=end
def test_index
ll = [11,12,13,14,12]
expected_1 = 1
expected_2 = 2
assert_equal(expected_1,ll.index(12),"first Value is 1")
# 条件を指定(12よりも大きい要素)
assert_equal(expected_2,ll.index{ |value| value > 12 },"first Value is 2")
end
=begin
リストから条件にあった要素の数を取得する
countメソッドは要素を「==」で判定する
===========Groovy===========
List ll = [11,12,13,14,13]
assert ll.count(13) == 2
assert ll.count {it % 2 == 0 } == 2
============================
=end
def test_grep_count
ll = [11,12,13,14,13]
expected = 2
assert_equal(expected,ll.count(13),"ll.count(13) => 2")
assert_equal(expected,ll.count{|item| item%2==0},"ll.count{|item| item%2==0} => 2")
end
=begin
リストから条件にあったもののリストを取得する
===========Groovy===========
List ll = [11,12,13,14]
assert ll.grep {it % 2 == 0 } == [12,14]
============================
=end
def test_grep
ll = [11,12,13,14]
expected = [12,14]
assert_equal(expected,ll.select{|item| item%2==0},"ll.select{|item| item%2==0} => [12,14]")
end
=begin
リストの末尾に要素を追加する
以下のようにすることもできる
・「ll << 15」のように破壊的に追加
・「ll.push 15,16」のように連続して要素を末尾に追加
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,13,14,15]
ll.add(15)
assert ll == expected
============================
=end
def test_add_data
ll = [11,12,13,14]
expected = [11,12,13,14,15]
ll.push 15
assert_equal(expected,ll,"ll => [11,12,13,14,15]")
end
=begin
要素の装入する位置をして、リストに要素を追加する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,15,13,14]
ll.add(2,15)
assert ll == expected
============================
=end
def test_add_selected_index
ll = [11,12,13,14]
expected = [11,12,15,13,14]
ll[2,0] = 15
assert_equal(expected,ll,"ll => [11, 12, 15, 13, 14] ")
end
=begin
リストから添字の位置に含まれる要素を取得する
リストの範囲外を指定した場合、nilを取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = 12
assert ll.get(1) == expected
assert ll[1] == expected
※リストの範囲外を指定するとIndexOutOfBoundsExceptionが発生する
============================
=end
def test_get
ll = [11,12,13,14]
expected = 12
assert_equal(expected,ll[1],"ll[1] => 12")
assert_equal(expected,ll.at(1),"ll.at(1) => 12.")
assert_nil(ll.at(5),"ll.at(nil) => 12.")
end
=begin
リストが空であるかどうか調べる
空の場合、trueとなる
===========Groovy===========
def ll = [11,12,13,14]
assert ll.isEmpty() == false
============================
=end
def test_list_empty
ll = [11,12,13,14]
expected = false
assert_equal(expected,ll.empty?,"ll.empty? is false / ll => [11,12,13,14]")
end
=begin
配列要素の数を取得する
配列の要素数に変更があった場合、要素数も変更になる
要素の中に配列が入った場合、配列が1要素として扱われる
===========Groovy===========
def ll = [11,12,13,14]
def expected = 4
assert ll.size() == expected
============================
=end
def test_size
ll = [11,12,13,14]
add = [15,16]
expected_1 = 4
expected_2 = 3
expected_3 = 4
expected_4 = 0
assert_equal(expected_1,ll.size,"ll.size is 4")
assert_equal(expected_1,ll.length,"ll.size is 4")
ll.pop
assert_equal(expected_2,ll.size,"ll.size is 3")
ll.push(add)
assert_equal(expected_3,ll.size,"ll.size is 4 / ll => [11,12,13,[15,16]")
ll.clear
assert_equal(expected_4,ll.size,"ll.size is 4 / ll => []")
end
=begin
リストから指定した範囲の要素のみのリストを取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [12,13]
assert ll.getAt(1..2) == expected
assert ll.getAt([1,2]) == expected
============================
=end
def test_selected_range
ll = [11,12,13,14]
expected_1 = [12,13]
expected_2 = [12,13,14]
assert_equal(expected_1,ll.slice(1,2),"ll.slice(1,2) => [12,13]")
assert_equal(expected_2,ll.slice(1..3),"ll.slice(1..2) => [12,13]")
assert_nil(ll.slice(5,1),"ll.slice(5,1) => nil")
end
=begin
リストの共通部分を取り出す
===========Groovy===========
def ll = [11,12,13,14]
def common = [12,13]
def expected = [12,13]
assert ll.intersect(common) == expected
============================
=end
def test_common
ll = [11,12,13,14]
common = [12,13]
expected = [12,13]
assert_equal(expected,ll & common,"ll & common => [12,13]")
end
=begin
配列の末尾を取り出す
===========Groovy===========
def ll = [11,12,13,14]
def expected_1 = 14
def expected_2 = [11,12,13]
assert ll.pop() == expected_1
assert ll == expected_2
============================
=end
def test_pop
ll = [11,12,13,14]
expected_1 = 14
expected_2 = 13
assert_equal(expected_1,ll.pop,"ll.pop => 14 / ll => [11,12,13]")
assert_equal(expected_2,ll.pop,"ll.pop => 13 / ll => [11,12]")
end
=begin
リスト内の要素の並び順を降順に変更したリストを取得する
メソッドの末尾に「!」をつけると自分自身のリストの並び順を変更する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [14,13,12,11]
assert ll.reverse() == expected
============================
=end
def test_reverse
ll = [11,12,13,14]
expected_1 = [14,13,12,11]
expected_2 = [11,12,13,14]
assert_equal(expected_1,ll.reverse,"ll.reverse => [14,13,12,11]")
assert_equal(expected_2,ll,"ll => [11,12,13,14]")
ll.reverse!
assert_equal(expected_1,ll,"ll => [11,12,13,14]")
end
=begin
リストをソートする
===========Groovy===========
def ll = [12,13,11,14]
def expected = [11,12,13,14]
assert ll.sort() == expected
============================
=end
def test_sort
ll = [12,13,11,14]
expected_1 = [11,12,13,14]
expected_2 = [12,13,11,14]
assert_equal(expected_1,ll.sort,"ll.sort => [11,12,13,14]")
assert_equal(expected_2,ll,"ll => [12,13,11,14]")
ll.sort!
assert_equal(expected_1,ll,"ll.sort => [11,12,13,14]")
end
=begin
リストの中で最大の値を取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = 14
assert ll.max() == expected
============================
=end
def test_max
ll = [11,12,13,14]
expected = 14
assert_equal(expected,ll.max,"ll.max is 14")
end
=begin
リストの中で最小の値を取得する
===========Groovy===========
def ll = [11,12,13,14]
def expected = 11
assert ll.min() == expected
============================
=end
def test_min
ll = [11,12,13,14]
expected = 11
assert_equal(expected,ll.min,"ll.max is 14")
end
=begin
リストの末尾にリストを追加する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,13,14,[15,16]]
ll.push([15,16])
assert ll == expected
============================
=end
def test_add_array_last
ll = [11,12,13,14]
expected = [11,12,13,14,[15,16]]
# 追加要素
add = [15,16]
ll.push(add)
assert_equal(expected,ll,"ll => [11, 12, 13, 14, [15, 16]]")
end
=begin
pushメソッドを使用せず、リストの末尾にリストを追加する
===========Groovy===========
def ll = [11,12,13,14]
def expected = [11,12,13,14,[15,16]]
ll <<[15,16]
assert ll == expected
============================
=end
def test_add_array_last_2
ll = [11,12,13,14]
expected = [11,12,13,14,[15,16]]
add = [15,16]
ll << add
assert_equal(expected,ll,"ll => [11, 12, 13, 14, [15, 16]]")
end
end
RubyのほうがGroovyよりも書きやすいや。。。
テストコードを書くときぐらいしか使いそうもないな
2013-01-20
[JavaScript]cloneNodeの動作が違って嵌ったので対処してみた
新年、明けましておめでとうございます。
今年もよろしくお願いします。
って言うの遅すぎというか今更ですねw
昨年末からかなりドタバタで忙しい状況が続きそろそろ収束して欲しいなぁとか思うところ
さて、表題の内容でハマりました・・・
イベント付きの要素をクローンしようとすると、正しく動作しなかった。
正確にはクローンするけれど、イベントも含めたクローンまではできなかった。
因みに、IE8,9は問題なくイベントを含めてクローンできてました
IE8,9はこれでイベントを含めてクローンできている
var clone = document.getElementById('list').cloneNode(true)
調べてみるとどうもIE7の仕様っぽい罠
同一プロセス内でcloneNodeした要素は、複製元のidを参照し続けるっぽい。(別プロセスなら問題ないっぽいけどどうすんだろ・・・)
なので、クローンしても元の要素が参照されっぱなしになる模様(ふざけんなって仕様ですね。)
対処方法
JQueryを使ってcloneを実施する
JQueryを使うことでイベントを含めたコピーがIE7でもできました。
JQueryを使える環境ではない場合の対処方法は思いつきませんでした。
※以下は試してみたけど、うまく動きませんでした(やり方が悪かったのかもしれませんが^^;)
・innerHTMLを使ってコピー元からコピー先に要素を渡してやれば回避できる
・コピー元の要素に含まれている要素をコピー先の要素にコピーしてやれば回避できる
こんな感じにすれば、イベントを含めたクローンがIE7でもできます。
手順は、こんな感じ
1.DOM要素空JQueryオブジェクトに変換
2.イベントを含めたクローン
3.JQueryオブジェクトからDOM要素に変換
ブラウザごとに対応として条件分岐でいれてやれば、ブラウザごとで意図どおりの動きになると思います。
ついでなので、JQueryとDOMの相互変換
▲DOM→jQuery
$()をつけてあげればよい
▲JQuery→DOM
jQueryオブジェクトの0番目の要素にアクセスすればよい
本当にIE爆発しろ!!
今年もよろしくお願いします。
って言うの遅すぎというか今更ですねw
昨年末からかなりドタバタで忙しい状況が続きそろそろ収束して欲しいなぁとか思うところ
さて、表題の内容でハマりました・・・
イベント付きの要素をクローンしようとすると、正しく動作しなかった。
正確にはクローンするけれど、イベントも含めたクローンまではできなかった。
因みに、IE8,9は問題なくイベントを含めてクローンできてました
IE8,9はこれでイベントを含めてクローンできている
var clone = document.getElementById('list').cloneNode(true)
調べてみるとどうもIE7の仕様っぽい罠
同一プロセス内でcloneNodeした要素は、複製元のidを参照し続けるっぽい。(別プロセスなら問題ないっぽいけどどうすんだろ・・・)
なので、クローンしても元の要素が参照されっぱなしになる模様(ふざけんなって仕様ですね。)
対処方法
JQueryを使ってcloneを実施する
JQueryを使うことでイベントを含めたコピーがIE7でもできました。
JQueryを使える環境ではない場合の対処方法は思いつきませんでした。
※以下は試してみたけど、うまく動きませんでした(やり方が悪かったのかもしれませんが^^;)
・innerHTMLを使ってコピー元からコピー先に要素を渡してやれば回避できる
・コピー元の要素に含まれている要素をコピー先の要素にコピーしてやれば回避できる
こんな感じにすれば、イベントを含めたクローンがIE7でもできます。
var tmp_dom_list = document.getElementById('list')
var tmp_jq_list = $(tmp_dom_list)
var tmp_jq_clone = $(tmp_jq_list).clone(true)
var clone = tmp_jq_clone[0]
手順は、こんな感じ
1.DOM要素空JQueryオブジェクトに変換
2.イベントを含めたクローン
3.JQueryオブジェクトからDOM要素に変換
ブラウザごとに対応として条件分岐でいれてやれば、ブラウザごとで意図どおりの動きになると思います。
ついでなので、JQueryとDOMの相互変換
▲DOM→jQuery
$()をつけてあげればよい
$(document.body)
▲JQuery→DOM
jQueryオブジェクトの0番目の要素にアクセスすればよい
var obj = $("select[name='test']");
var val = obj[0]
本当にIE爆発しろ!!
2012-12-20
[戯言]USキーボードのノートPC
手がUSキーボードになじんでしまっているので、常用(?)だと日本語キーボードキツいです。。。
選んでる時点でどうなの?っていう気がしなくもないですが^^;
で、販売しているメーカーを調べてみた。
- lenovo
- Apple
- DELL
- hp
- SONY
※SONYに至っては有償ですし、hpはモデル(機種番号)自体が異なってる模様
あんまり種類がないのね・・・
選んでる時点でどうなの?っていう気がしなくもないですが^^;
で、販売しているメーカーを調べてみた。
- lenovo
- Apple
- DELL
- hp
- SONY
※SONYに至っては有償ですし、hpはモデル(機種番号)自体が異なってる模様
あんまり種類がないのね・・・
2012-12-19
[Ruby]ActiveRecordとsqlite3の接続方法
ついカッとなって久しぶりに使いたくなった。(ちょっとしたものを作りたくなったので)
昔のsqlite3への接続方法から仕様が変更されていた。
▲昔の接続方法
▲今の接続方法
▲変更点
- DBファイル指定がデータベース指定へ
- テーブル名の変更がset_table_nameからtable_nameへ
ざっと触った感じだとCRUD操作はあんまし変わってないように思える
時間があれば、昔のコードを直しておくか
昔のsqlite3への接続方法から仕様が変更されていた。
▲昔の接続方法
class Hoge < ActiveRecord::Base end Hoge.establish_connection( :adapter => 'sqlite3', :dbfile => 'fuga' ) Hoge.set_table_name "fuga"
▲今の接続方法
class Hoge < ActiveRecord::Base end Hoge.establish_connection( :adapter => 'sqlite3', :database => 'fuga' ) Hoge.table_name = "fuga"
▲変更点
- DBファイル指定がデータベース指定へ
- テーブル名の変更がset_table_nameからtable_nameへ
ざっと触った感じだとCRUD操作はあんまし変わってないように思える
時間があれば、昔のコードを直しておくか
2012-12-18
[Linux]rpmbuildコマンドについてメモ
rpmbuildコマンドのオプションについてメモをしておく
▲コマンドオプション
ba:SPECファイルを用いてRPMファイルとSRPMファイルをビルドする
bb:SPECファイルを用いてRPMファイルをビルドする
bs:SPECファイルを用いてSRPMファイルをビルドする
ta:ソースコードのtarballファイル(tar+gzipやtar+bzip2)を用いてRPMファイルとSRPMファイルをビルドする
tb:ソースコードのtarballファイル(tar+gzipやtar+bzip2)を用いてRPMファイルをビルドする
ts:ソースコードのtarballファイル(tar+gzipやtar+bzip2)を用いてSRPMファイルをビルドする
--target:ビルド対象のプラットフォームを指定する
--sort-circuit:指定セクション以降からのビルド作業を実施する
bp:prepセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
bc:buildセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
bi:installセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
bl:filesセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
rmsource:ビルド作業後,指定されたソースファイルを削除します.
rmspec:ビルド実行後,指定されたSPECファイルを削除する
▲ビルドに使用するディレクトリ
BUILD:ビルド作業に使用する
RPMS:ビルド成功時にRPMファイルを保存する(アーキテクチャ別にサブディレクトリが分けられる)
SRPMS:ビルド成功時にSRPMファイルを保存する
SOURCES:ビルドに必要なソースファイルやパッチファイルを配置する
SPECS:ビルドに必要なSPECファイルを配置する
▲よく出るビルド依存性の失敗の対処(出やすい)
$rpmbuild -ba rpmbuild/SPEC/hoge.spec
エラー: ビルド依存性の失敗:
hoge-develはfuga.i386 に必要とされています
原因
該当RPMを作成するのに必要なパッケージがインストールされていないこと
対処
不足しているパッケージをyumもしくはrpmでインストールしてから再度rpmbuildを実行する
これだけメモしておけば十分だろ。
あとはspecファイルだえ作成できればね。
▲コマンドオプション
ba:SPECファイルを用いてRPMファイルとSRPMファイルをビルドする
bb:SPECファイルを用いてRPMファイルをビルドする
bs:SPECファイルを用いてSRPMファイルをビルドする
ta:ソースコードのtarballファイル(tar+gzipやtar+bzip2)を用いてRPMファイルとSRPMファイルをビルドする
tb:ソースコードのtarballファイル(tar+gzipやtar+bzip2)を用いてRPMファイルをビルドする
ts:ソースコードのtarballファイル(tar+gzipやtar+bzip2)を用いてSRPMファイルをビルドする
--target:ビルド対象のプラットフォームを指定する
--sort-circuit:指定セクション以降からのビルド作業を実施する
bp:prepセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
bc:buildセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
bi:installセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
bl:filesセクション以降を実行する(「--short-circuit」オプションと一緒に使用する)
rmsource:ビルド作業後,指定されたソースファイルを削除します.
rmspec:ビルド実行後,指定されたSPECファイルを削除する
▲ビルドに使用するディレクトリ
BUILD:ビルド作業に使用する
RPMS:ビルド成功時にRPMファイルを保存する(アーキテクチャ別にサブディレクトリが分けられる)
SRPMS:ビルド成功時にSRPMファイルを保存する
SOURCES:ビルドに必要なソースファイルやパッチファイルを配置する
SPECS:ビルドに必要なSPECファイルを配置する
▲よく出るビルド依存性の失敗の対処(出やすい)
$rpmbuild -ba rpmbuild/SPEC/hoge.spec
エラー: ビルド依存性の失敗:
hoge-develはfuga.i386 に必要とされています
原因
該当RPMを作成するのに必要なパッケージがインストールされていないこと
対処
不足しているパッケージをyumもしくはrpmでインストールしてから再度rpmbuildを実行する
これだけメモしておけば十分だろ。
あとはspecファイルだえ作成できればね。
2012-12-17
[Emacs]しょうもないネタ(エッチなのはry)
釣りではないですよ。。。
このあたりをロードして
このあたりを開くと・・・
アレなファイルは以下のものです。ファイルのタイトルからしてアレですがw
・CENSORSHIP
・celibacy.1
・condom.1
・sex.6
あ、ちなみにrpmでインストールしたEmacsには入ってませんのであしからず
このあたりをロードして
$emacs -l /usr/share/emacs/24.1/lisp/play/meese.elc
このあたりを開くと・・・
/usr/share/emacs/24.1/etc/sex.6
アレなファイルは以下のものです。ファイルのタイトルからしてアレですがw
・CENSORSHIP
・celibacy.1
・condom.1
・sex.6
あ、ちなみにrpmでインストールしたEmacsには入ってませんのであしからず
2012-12-16
[Linux]メモリ管理の周りの基礎を勉強した
ひとつ賢くなった・・・はず・・・。
▲メモリ種類
物理メモリの配分は2種類あってそれぞれ以下の呼び名がある
・Lowメモリ(1-896MB)
・Highメモリ(896ME以上)
Highメモリはユーザプロセスが使用するので説明不要だと思う
Lowメモリは以下のことをしている
・カーネルコードのマッピング
・カーネルのデータ領域の確保
・物理アドレスと論理アドレスのマッピングテーブルの確保(CPUのMMU機能を使用)
x86_64だとサイズの制限がなくなる(LowメモリとHighメモリの区別が無くなる)
▲メモリの割当
共有マッピングと呼ばれる機能を使って、メモリの割当を実施している
共有マッピングは以下の2種類ある
・コピー・オン・ライト
・デマンド・ページング
コピー・オン・ライト
プロセスAとプロセスBがあったとし、メモリは同一のものを使用しているとする
1.プロセスBがメモリを変更する
2.ほぼ同じタイミングでプロセスAもメモリに変更する
3.カーネルはプロセスBが変更しているので、プロセスBが変更しているメモリが変更されないように書き込み禁止にする
4.カーネルは、メモリの内容をプロセスA用にコピーする
5.プロセスAはコピー先のメモリに対して変更処理をする
書き込みを初めて行うときにメモリの内容をコピーする処理
デマンド・ページング
プロセスAを起動したとする
1.カーネルはプロセスAの起動前にプロセスBが使用するファイルなどの情報だけを先に読み込む
- 論理アドレスの情報を登録する
2.プロセスAを起動する
3.プロセスAが登録された論理アドレスの情報を使用する
4.カーネルは論理アドレスに何もない(ページフォールト例外を検知)ことを受け取る
5.カーネルはプロセスAが使用する情報をメモリ上に読み込む
必要なものを必要なときにだけ読み込む処理
▲メモリの解放
物理メモリを要求した時にメモリ割当が可能な場合、そのままメモリの割当を実施する
割当が不可能な場合
1.プロセスがブロッキング可能かどうか確認する
- 不可能な場合、割当に失敗にする
2.カーネル内部で以下の3種類のいずれかを実施する
- OOM Killer
- スワップアウト実行(swappiness値が大きいと実行されやすい)
- ディスクキャッシュの解放
3.メモリ割当可能かどうか再確認する
解放対象は、主にダーティなデータが対象になる
スワップアウト:メモリ上のActive(anon)やInactive(anon)のLRUリストに登録されているAnonymousメモリを解放することをいう
- ActiveやIncativeは/proc/meminfoやpmapコマンド(-xオプション付き)で確認できる
簡単なメモだけど、まぁいいや^^;
▲メモリ種類
物理メモリの配分は2種類あってそれぞれ以下の呼び名がある
・Lowメモリ(1-896MB)
・Highメモリ(896ME以上)
Highメモリはユーザプロセスが使用するので説明不要だと思う
Lowメモリは以下のことをしている
・カーネルコードのマッピング
・カーネルのデータ領域の確保
・物理アドレスと論理アドレスのマッピングテーブルの確保(CPUのMMU機能を使用)
x86_64だとサイズの制限がなくなる(LowメモリとHighメモリの区別が無くなる)
▲メモリの割当
共有マッピングと呼ばれる機能を使って、メモリの割当を実施している
共有マッピングは以下の2種類ある
・コピー・オン・ライト
・デマンド・ページング
コピー・オン・ライト
プロセスAとプロセスBがあったとし、メモリは同一のものを使用しているとする
1.プロセスBがメモリを変更する
2.ほぼ同じタイミングでプロセスAもメモリに変更する
3.カーネルはプロセスBが変更しているので、プロセスBが変更しているメモリが変更されないように書き込み禁止にする
4.カーネルは、メモリの内容をプロセスA用にコピーする
5.プロセスAはコピー先のメモリに対して変更処理をする
書き込みを初めて行うときにメモリの内容をコピーする処理
デマンド・ページング
プロセスAを起動したとする
1.カーネルはプロセスAの起動前にプロセスBが使用するファイルなどの情報だけを先に読み込む
- 論理アドレスの情報を登録する
2.プロセスAを起動する
3.プロセスAが登録された論理アドレスの情報を使用する
4.カーネルは論理アドレスに何もない(ページフォールト例外を検知)ことを受け取る
5.カーネルはプロセスAが使用する情報をメモリ上に読み込む
必要なものを必要なときにだけ読み込む処理
▲メモリの解放
物理メモリを要求した時にメモリ割当が可能な場合、そのままメモリの割当を実施する
割当が不可能な場合
1.プロセスがブロッキング可能かどうか確認する
- 不可能な場合、割当に失敗にする
2.カーネル内部で以下の3種類のいずれかを実施する
- OOM Killer
- スワップアウト実行(swappiness値が大きいと実行されやすい)
- ディスクキャッシュの解放
3.メモリ割当可能かどうか再確認する
解放対象は、主にダーティなデータが対象になる
スワップアウト:メモリ上のActive(anon)やInactive(anon)のLRUリストに登録されているAnonymousメモリを解放することをいう
- ActiveやIncativeは/proc/meminfoやpmapコマンド(-xオプション付き)で確認できる
簡単なメモだけど、まぁいいや^^;
2012-12-15
[Linux]RPMを作成するSPECファイル(Emacs用)を書いてみた
以前から作成しようと試みていて、ちょいちょいやってた内容を今ここにまとめておく。
誰か(主に俺)の役に立つと信じている。
・ヘッダーセクション
Sourceやインストールするための仮想なディレクトリを設定する
以下に見本を記載する
・prepセクション
build準備を実施します。
アーカイブの展開やパッチを当てたりする
ソースとして指定したアーカイブファイルをファイル名から最も適したコマンドを自動検知し,展開を実行
ヘッダ中に Patch: で示されているn番目のパッチを当てたりもできます
・ビルドセクション
単純にビルドを実施するセクション
普通のコンパイル手順を記載するのみです。
マクロを作っておくなどの処理もここで実施します
・インストール(トリガースクリプトと言われる)
ここのセクションがあるので、ビルドはrootユーザもしくはsudoを使ったものでやってはいけないです。
RPM経由ではない(make install)インストールがされてしまいます。
以下の順序で実施する
1.前準備
%pretrans
2.パッケージのインストール
%trigerprein
%pre
%post
3.古いパッケージの削除(パッケージの削除も相当する)
%preun
%postun
%trigerpostun
4.後始末
%triggerpostun
%posttrans
・クリーン
ビルドに使ったファイルなどを後始末する
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
・files
パッケージ化するファイルの一覧を記載します。
以下の点を注意して記載します。
・仮想ディレクトリにインストールされたファイルを全て書く
・実際にインストールされるパスを書く
以下の手順でやれば、効率よくできると思います。(都合2回ビルドしますが)
1.エラーになるのは分かりつつ、filesセクションには何も書かずにrpmbuildを実施する
2.最後のパッケージングで、「未伸張のファイルが見つかりました」というエラーとともに、インストールするファイルの一覧が表示される。
3.表示されたエラーファイルを元に、specファイルのfilesセクションを書いて、再度ビルド(ほぼ全て書けばよいでしょう)
ここまで学習したので、書いてみた。
完成したのが以下のSPECファイル
これをソースコードとともに以下のような配置でおく
以下のコマンドでビルドを実施する
$rpmbuild -ba rpmbuild/SPEC/emacs.spec
ビルドが完了すると、RPMディレクトリにemacsのrpmファイルができます。
上記のspecファイルでは、削除方法をinstallセクションに記載していないので正しく削除できません。必要に応じて追加してください。
※注意することは、ビルドをrootユーザーで実施しないこと(rpmを作成途中、本当にインストールしてしまうのでrpm管理ができなくなります)
因に、本家のspecファイルに自分用のカスタマイズ(不要と思われるものを排除)したものを掲載しておきます。
・specファイル
・Desktopファイル(gnome用)
これでrpmも自分で作れるな・・・多分・・・。
ここを参考にrpmの作成を勉強しました(日本語ページだと一番詳しく書かれていた)
誰か(主に俺)の役に立つと信じている。
・ヘッダーセクション
Sourceやインストールするための仮想なディレクトリを設定する
以下に見本を記載する
Summary: hoge.spec #specファイルの説明 Name: hoge #パッケージ名 Version: 2.54 #ソースのバージョン番号 Release: 3 #パッケージのリリース番号(ソースのバージョンと関係無) Group: Applications #パッケージ分類(何か独自のものがあればよい) Source: hoge.tar.gz #オリジナルのソースファイルの一次配布 ftp サイトを記述(自分のtopdir:SOURCES ディレクトリにソースファイルがあれば問題無) Copyright: kurobara App #アプリのコピーライト Packager: kurobara #パッケージングを実施した人物(rpm -qiでは表示されない) URL: http://hoge.fuga #ダウンロード元(rpm -qiでは表示されない) BuildRoot: /home/hoge #仮想のインストール先 Patch: hoge.patch #パッチの置き場所を記述するPatch1,Patch2...という感じで複数記述可能 %package docs #docsパッケージの作成タグ Summary: Documents package #docsパッケージの説明 Group: Applications #docsパッケージの分類 %description #パッケージの説明文のタグ hogehogefugafuga. #パッケージの説明
・prepセクション
build準備を実施します。
アーカイブの展開やパッチを当てたりする
ソースとして指定したアーカイブファイルをファイル名から最も適したコマンドを自動検知し,展開を実行
ヘッダ中に Patch
・ビルドセクション
単純にビルドを実施するセクション
普通のコンパイル手順を記載するのみです。
マクロを作っておくなどの処理もここで実施します
・インストール(トリガースクリプトと言われる)
ここのセクションがあるので、ビルドはrootユーザもしくはsudoを使ったものでやってはいけないです。
RPM経由ではない(make install)インストールがされてしまいます。
以下の順序で実施する
1.前準備
%pretrans
2.パッケージのインストール
%trigerprein
%pre
%post
3.古いパッケージの削除(パッケージの削除も相当する)
%preun
%postun
%trigerpostun
4.後始末
%triggerpostun
%posttrans
・クリーン
ビルドに使ったファイルなどを後始末する
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
・files
パッケージ化するファイルの一覧を記載します。
以下の点を注意して記載します。
・仮想ディレクトリにインストールされたファイルを全て書く
・実際にインストールされるパスを書く
以下の手順でやれば、効率よくできると思います。(都合2回ビルドしますが)
1.エラーになるのは分かりつつ、filesセクションには何も書かずにrpmbuildを実施する
2.最後のパッケージングで、「未伸張のファイルが見つかりました」というエラーとともに、インストールするファイルの一覧が表示される。
3.表示されたエラーファイルを元に、specファイルのfilesセクションを書いて、再度ビルド(ほぼ全て書けばよいでしょう)
ここまで学習したので、書いてみた。
完成したのが以下のSPECファイル
Summary: GNU Emacs text editor
Name: emacs
Epoch: 1
Version: 24.1
Release: 1
License: GPLv3+
URL: http://www.gnu.org/software/emacs/
Group: Applications/Editors
Source0: ftp://ftp.gnu.org/gnu/emacs/emacs-%{version}.tar.bz2
Buildroot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: atk-devel, cairo-devel, desktop-file-utils, freetype-devel, fontconfig-devel, dbus-devel, giflib-devel, glibc-devel, gtk2-devel, libpng-devel
BuildRequires: libjpeg-devel, libtiff-devel, libX11-devel, libXau-devel, libXdmcp-devel, libXrender-devel, libXt-devel
BuildRequires: libXpm-devel, ncurses-devel, xorg-x11-proto-devel, zlib-devel
BuildRequires: autoconf, automake, bzip2, cairo, texinfo
%ifarch %{ix86}
BuildRequires: setarch
%endif
%define site_lisp %{_datadir}/emacs/site-lisp
%description
This package provides an emacs binary with support for X windows.
This package is built by kurobara.
%define emacs_libexecdir %{_libexecdir}/emacs/%{version}/%{_host}
%prep
%setup -q
%ifarch %{ix86}
%define setarch setarch %{_arch} -R
%else
%define setarch %{nil}
%endif
%build
export CFLAGS="-DMAIL_USE_LOCKF $RPM_OPT_FLAGS"
%configure --with-dbus --with-gif --with-jpeg --with-png --with-rsvg \
--with-tiff --with-xft --with-xpm --with-x-toolkit=gtk
%__make bootstrap
%{setarch} %__make %{?_smp_mflags}
%install
rm -rf %{buildroot}
make install INSTALL="%{__install} -p" DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root)
/usr/bin/*
/usr/libexec/*
/usr/share/*
/var/games/emacs/*
これをソースコードとともに以下のような配置でおく
rpmbuild |-SOURCE | |-emacs-24.1.tar.bz2 | |-SPEC |-emacs.spec
以下のコマンドでビルドを実施する
$rpmbuild -ba rpmbuild/SPEC/emacs.spec
ビルドが完了すると、RPMディレクトリにemacsのrpmファイルができます。
上記のspecファイルでは、削除方法をinstallセクションに記載していないので正しく削除できません。必要に応じて追加してください。
※注意することは、ビルドをrootユーザーで実施しないこと(rpmを作成途中、本当にインストールしてしまうのでrpm管理ができなくなります)
因に、本家のspecファイルに自分用のカスタマイズ(不要と思われるものを排除)したものを掲載しておきます。
・specファイル
Summary: GNU Emacs text editor
Name: emacs
Epoch: 1
Version: 24.2
Release: 21%{?dist}.3
License: GPLv3+
URL: http://www.gnu.org/software/emacs/
Group: Applications/Editors
Source0: ftp://ftp.gnu.org/gnu/emacs/emacs-%{version}.tar.bz2
Source1: emacs.desktop
#Source3: dotemacs.el
#Source4: site-start.el
#Source18: default.el
Buildroot: /usr/local/share/%{name}-%{version}-root
BuildRequires: atk-devel, cairo-devel, desktop-file-utils, freetype-devel, fontconfig-devel, dbus-devel, giflib-devel, glibc-devel, gtk2-devel, libpng-devel
BuildRequires: libjpeg-devel, libtiff-devel, libX11-devel, libXau-devel, libXdmcp-devel, libXrender-devel, libXt-devel
BuildRequires: libXpm-devel, ncurses-devel, xorg-x11-proto-devel, zlib-devel
BuildRequires: autoconf, automake, bzip2, cairo, texinfo
%ifarch %{ix86}
BuildRequires: setarch
%endif
Requires: emacs-common = %{epoch}:%{version}-%{release}
Requires: librsvg2
# Desktop integration
BuildRequires: desktop-file-utils
Requires: desktop-file-utils
Conflicts: gettext < 0.10.40
Provides: emacs(bin)
Requires: m17n-db-datafiles
# C and build patches
# Lisp and doc patches
%define paranoid 1
%define expurgate 1
%define site_lisp %{_datadir}/emacs/site-lisp
%define site_start_d %{site_lisp}/site-start.d
%define bytecompargs -batch --no-init-file --no-site-file -f batch-byte-compile
%define pkgconfig %{_datadir}/pkgconfig
%description
Emacs is a powerful, customizable, self-documenting, modeless text
editor. Emacs contains special code editing features, a scripting
language (elisp), and the capability to read mail, news, and more
without leaving the editor.
This package provides an emacs binary with support for X windows.
%package common
Summary: Emacs common files
Group: Applications/Editors
Requires(preun): %{_sbindir}/alternatives, /sbin/install-info, dev
Requires(posttrans): %{_sbindir}/alternatives
Requires(post): /sbin/install-info, dev
Obsoletes: emacs-leim
%description common
Emacs is a powerful, customizable, self-documenting, modeless text
editor. Emacs contains special code editing features, a scripting
language (elisp), and the capability to read mail, news, and more
without leaving the editor.
This package contains all the common files needed by emacs or emacs-nox.
%package el
Summary: Emacs Lisp source files included with Emacs.
Group: Applications/Editors
%description el
Emacs-el contains the emacs-elisp sources for many of the elisp
programs included with the main Emacs text editor package.
You need to install emacs-el only if you intend to modify any of the
Emacs packages or see some elisp examples.
%define emacs_libexecdir %{_libexecdir}/emacs/%{version}/%{_host}
%prep
%setup -q
# we prefer our emacs.desktop file
cp %SOURCE1 etc/emacs.desktop
grep -v "tetris.elc" lisp/Makefile.in > lisp/Makefile.in.new \
&& mv lisp/Makefile.in.new lisp/Makefile.in
# avoid trademark issues
%if %{paranoid}
rm -f lisp/play/tetris.el lisp/play/tetris.elc
%endif
%if %{expurgate}
rm -f etc/sex.6 etc/condom.1 etc/celibacy.1 etc/COOKIES etc/future-bug etc/JOKES
%endif
%ifarch %{ix86}
%define setarch setarch %{_arch} -R
%else
%define setarch %{nil}
%endif
%build
export CFLAGS="-DMAIL_USE_LOCKF $RPM_OPT_FLAGS"
#we patch configure.in so we have to do this
%configure --with-dbus --with-gif --with-jpeg --with-png --with-rsvg \
--with-tiff --with-xft --with-xpm --with-x-toolkit=gtk
%__make bootstrap
%{setarch} %__make %{?_smp_mflags}
# remove versioned file so that we end up with .1 suffix and only one DOC file
rm src/emacs-%{version}.*
%__make %{?_smp_mflags} -C lisp updates
# Create pkgconfig file
cat > emacs.pc << EOF
sitepkglispdir=%{site_lisp}
sitestartdir=%{site_start_d}
Name: emacs
Description: GNU Emacs text editor
Version: %{epoch}:%{version}
EOF
# Create macros.emacs RPM macro file
cat > macros.emacs << EOF
%%_emacs_version %{version}
%%_emacs_ev %{?epoch:%{epoch}:}%{version}
%%_emacs_evr %{?epoch:%{epoch}:}%{version}-%{release}
%%_emacs_sitelispdir %{site_lisp}
%%_emacs_sitestartdir %{site_start_d}
%%_emacs_bytecompile /usr/bin/emacs %bytecompargs
EOF
%install
rm -rf %{buildroot}
make install INSTALL="%{__install} -p" DESTDIR=%{buildroot}
# let alternatives manage the symlink
rm %{buildroot}%{_bindir}/emacs
# make sure movemail isn't setgid
chmod 755 %{buildroot}%{emacs_libexecdir}/movemail
mkdir -p %{buildroot}%{site_lisp}
mv %{buildroot}%{_bindir}/{etags,etags.emacs}
mkdir -p %{buildroot}%{site_lisp}/site-start.d
# default initialization file
mkdir -p %{buildroot}%{_sysconfdir}/skel
# install pkgconfig file
mkdir -p %{buildroot}/%{pkgconfig}
install -p -m 0644 emacs.pc %{buildroot}/%{pkgconfig}
# install rpm macro definition file
mkdir -p %{buildroot}%{_sysconfdir}/rpm
install -p -m 0644 macros.emacs %{buildroot}%{_sysconfdir}/rpm/
# after everything is installed, remove info dir
rm -f %{buildroot}%{_infodir}/dir
rm %{buildroot}%{_localstatedir}/games/emacs/*
# install desktop file
mkdir -p %{buildroot}%{_datadir}/applications
desktop-file-install --dir=%{buildroot}%{_datadir}/applications \
%SOURCE1
#
# create file lists
#
rm -f *-filelist {common,el}-*-files
( TOPDIR=${PWD}
cd %{buildroot}
find .%{_datadir}/emacs/%{version}/lisp \
.%{_datadir}/emacs/%{version}/leim \
.%{_datadir}/emacs/site-lisp \( -type f -name '*.elc' -fprint $TOPDIR/common-lisp-none-elc-files \) -o \( -type d -fprintf $TOPDIR/common-lisp-dir-files "%%%%dir %%p\n" \) -o \( -name '*.el.gz' -fprint $TOPDIR/el-bytecomped-files -o -fprint $TOPDIR/common-not-comped-files \)
)
# put the lists together after filtering ./usr to /usr
sed -i -e "s|\.%{_prefix}|%{_prefix}|" *-files
cat common-*-files > common-filelist
cat el-*-files common-lisp-dir-files > el-filelist
%clean
rm -rf %{buildroot}
%post
update-desktop-database &> /dev/null || :
touch --no-create %{_datadir}/icons/hicolor
if [ -x %{_bindir}/gtk-update-icon-cache ] ; then
%{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor || :
fi
%postun
update-desktop-database &> /dev/null || :
touch --no-create %{_datadir}/icons/hicolor
if [ -x %{_bindir}/gtk-update-icon-cache ] ; then
%{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor || :
fi
%preun
alternatives --remove emacs %{_bindir}/emacs-%{version} || :
%posttrans
#check if there is "remainder" old version, which was not deleted
if alternatives --display emacs > /dev/null; then
VER=$(alternatives --display emacs | sed -ne 's/.*emacs-\([0-9\.]\+\).*/\1/p' | head -1)
if [ ${VER} != %{version} ]; then
alternatives --remove emacs %{_bindir}/emacs-${VER} || :
fi
fi
#end check
alternatives --install %{_bindir}/emacs emacs %{_bindir}/emacs-%{version} 80 || :
%post common
for f in %{info_files}; do
/sbin/install-info %{_infodir}/$f %{_infodir}/dir 2> /dev/null || :
done
%preun common
alternatives --remove emacs.etags %{_bindir}/etags.emacs || :
if [ "$1" = 0 ]; then
for f in %{info_files}; do
/sbin/install-info --delete %{_infodir}/$f %{_infodir}/dir 2> /dev/null || :
done
fi
%posttrans common
alternatives --install %{_bindir}/etags emacs.etags %{_bindir}/etags.emacs 80 \
--slave %{_mandir}/man1/etags.1.gz emacs.etags.man %{_mandir}/man1/etags.emacs.1.gz
%files
%defattr(-,root,root)
%{_bindir}/emacs-%{version}
%dir %{_libexecdir}/emacs
%dir %{_libexecdir}/emacs/%{version}
%dir %{emacs_libexecdir}
%{_datadir}/applications/emacs.desktop
%{_datadir}/icons/hicolor/*/apps/emacs.png
%{_datadir}/icons/hicolor/*/apps/emacs22.png
%{_datadir}/icons/hicolor/scalable/apps/emacs.svg
%{_datadir}/icons/hicolor/scalable/mimetypes/emacs-document.svg
%files -f common-filelist common
%defattr(-,root,root)
#%config(noreplace) %{_sysconfdir}/skel/.emacs
%config(noreplace) %{_sysconfdir}/rpm/macros.emacs
%doc etc/NEWS BUGS README
%exclude %{_bindir}/emacs-*
%{_bindir}/*
%{_mandir}/*/*
%{_infodir}/*
%dir %{_datadir}/emacs
%dir %{_datadir}/emacs/%{version}
%{_datadir}/emacs/%{version}/etc
%{_datadir}/emacs/%{version}/site-lisp
%{_libexecdir}/emacs
%files -f el-filelist el
%defattr(-,root,root)
%{pkgconfig}/emacs.pc
%dir %{_datadir}/emacs
%dir %{_datadir}/emacs/%{version}
・Desktopファイル(gnome用)
[Desktop Entry] Name=Emacs GenericName=Text Editor Comment=Edit text Comment[zh_TW]=編輯文字 MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; Exec=emacs %f Icon=emacs.png Type=Application Terminal=false Categories=Application;Utility;TextEditor;X-Red-Hat-Base; Encoding=UTF-8 StartupWMClass=Emacs
これでrpmも自分で作れるな・・・多分・・・。
ここを参考にrpmの作成を勉強しました(日本語ページだと一番詳しく書かれていた)
2012-12-14
[Linux]I/Oスケジューラを少し勉強した
所謂エレベータ・アルゴリズムの話。
勉強したといっても障りだけで、本質の理解ではなかったりする。
単にパフォーマンスに関わるところだったりするからって理由。
▲データの流れ
1.ファイルシステムは転送対象のデータ(物理ディスクの連続セクタごと)をまとめたオブジェクトをカーネル内部で作成する
- bioオブジェクトという
2.1で作成したbioオブジェクトをI/Oスケジューラに渡す
3.I/Oスケジューラは、受け取った複数のbioオブジェクトをまとめてリクエストオブジェクトを作成する
- このときbioオブジェクトがつながるリクエストオブジェクトがあれば、既存のリクエストオブジェクトにbioオブジェクトを追加する
- 存在しなかった場合、新規にリクエストオブジェクトを作成する
4.リクエストオブジェクトで指定された領域ごとにデータの読み書きを実施する
- リクエストオブジェクトから更にディスパッチキューにオブジェクトが流れる
- ディスパッチキューから更にデバイスドライバにデータが流れて、物理ディスクのI/Oを実施する(I/Oはリクエストオブジェクトに従って実施する)
※I/Oスケジューラによって3以降の流れは変化します
▲I/Oスケジューラの種類
・noop:サブキューを1本だけ持っており、受け取ったbioオブジェクトの順に処理を実施する(所謂FIFO)
・cfq:プロセスのプロセスIDをキーとしたハッシュで64本のサブキューに分類する。分類後、各サブキューから順に公平に処理を実施する(プロセスごとに公平な処理)
・deadline:読み込みと書き込みのサブキューを持つ。bioオブジェクトに対応したセクタの位置に応じて既存のリクエストを順に処理する(ディスクのヘッドの動作を最小にする)。ヘッド位置とbioオブジェクトの挿入によって処理できない既存のbioオブジェクトもできてしまうので、回避策として一定時間(読み込み0.5sec,書き込み5sec)処理されなかったリクエストを優先的に処理をする
・anticipatory:deadlineスケジューラに待ち時間(0.7sec)をつけたもの。この待ち時間は、現在処理中のリクエストと同じ(もしくは前後)ヘッド位置の処理リクエストがくる可能性が高いことが想定されるため。待ち時間の間に同じヘッド位置のリクエストが来た場合、リクエストが来たものを優勢的に処理をする
▲現在使用しているI/Oスケジューラを確認する
以下のコマンドで作成できる
もしくは「/sys/block/<デバイス名>/queue/scheduler 」のファイルに記載された「[]」を確認する
▲使用するスケジューラを変更する
「/sys/block/<デバイス名>/queue/scheduler」を以下のコマンドで書き換えればできます
上記はnoopを設定したが、deadlineなどに変更することも出来る
※エディタを使用した変更はできないので注意すること
因に、システムのデフォルトI/Oスケジューラを変更する場合、「/boot/grub/grub.conf」のカーネル起動オプションに以下を追加すればよい
外付けのディスクなどは変更しないほうがよい
というのも、ストレージ装置のコントローラーが既に最適化を行っているため
下手にI/Oスケジューラを変更すると却ってパフォーマンスが落ちてしまいます
ついでに言うとioniceコマンドを使って、以下のようにプロセスI/Oを変更することもできたりますwww
・Real time:システム上のどのような処理に対しても優先して実行する
・Best Effort:デフォルトの設定で、スケジューラに従って実行する
・Idle:システム上のすべての処理に対して後回しに実行する(システムがアイドル状態のときに実行される)
ioniceコマンドは数値が低いものが優先度高いです。。。
勉強したといっても障りだけで、本質の理解ではなかったりする。
単にパフォーマンスに関わるところだったりするからって理由。
▲データの流れ
1.ファイルシステムは転送対象のデータ(物理ディスクの連続セクタごと)をまとめたオブジェクトをカーネル内部で作成する
- bioオブジェクトという
2.1で作成したbioオブジェクトをI/Oスケジューラに渡す
3.I/Oスケジューラは、受け取った複数のbioオブジェクトをまとめてリクエストオブジェクトを作成する
- このときbioオブジェクトがつながるリクエストオブジェクトがあれば、既存のリクエストオブジェクトにbioオブジェクトを追加する
- 存在しなかった場合、新規にリクエストオブジェクトを作成する
4.リクエストオブジェクトで指定された領域ごとにデータの読み書きを実施する
- リクエストオブジェクトから更にディスパッチキューにオブジェクトが流れる
- ディスパッチキューから更にデバイスドライバにデータが流れて、物理ディスクのI/Oを実施する(I/Oはリクエストオブジェクトに従って実施する)
※I/Oスケジューラによって3以降の流れは変化します
▲I/Oスケジューラの種類
・noop:サブキューを1本だけ持っており、受け取ったbioオブジェクトの順に処理を実施する(所謂FIFO)
・cfq:プロセスのプロセスIDをキーとしたハッシュで64本のサブキューに分類する。分類後、各サブキューから順に公平に処理を実施する(プロセスごとに公平な処理)
・deadline:読み込みと書き込みのサブキューを持つ。bioオブジェクトに対応したセクタの位置に応じて既存のリクエストを順に処理する(ディスクのヘッドの動作を最小にする)。ヘッド位置とbioオブジェクトの挿入によって処理できない既存のbioオブジェクトもできてしまうので、回避策として一定時間(読み込み0.5sec,書き込み5sec)処理されなかったリクエストを優先的に処理をする
・anticipatory:deadlineスケジューラに待ち時間(0.7sec)をつけたもの。この待ち時間は、現在処理中のリクエストと同じ(もしくは前後)ヘッド位置の処理リクエストがくる可能性が高いことが想定されるため。待ち時間の間に同じヘッド位置のリクエストが来た場合、リクエストが来たものを優勢的に処理をする
▲現在使用しているI/Oスケジューラを確認する
以下のコマンドで作成できる
$lsblk -t
もしくは「/sys/block/<デバイス名>/queue/scheduler 」のファイルに記載された「[]」を確認する
▲使用するスケジューラを変更する
「/sys/block/<デバイス名>/queue/scheduler」を以下のコマンドで書き換えればできます
$echo "noop" > /sys/block/<デバイス名>/queue/scheduler
上記はnoopを設定したが、deadlineなどに変更することも出来る
※エディタを使用した変更はできないので注意すること
因に、システムのデフォルトI/Oスケジューラを変更する場合、「/boot/grub/grub.conf」のカーネル起動オプションに以下を追加すればよい
elevator=noop
外付けのディスクなどは変更しないほうがよい
というのも、ストレージ装置のコントローラーが既に最適化を行っているため
下手にI/Oスケジューラを変更すると却ってパフォーマンスが落ちてしまいます
ついでに言うとioniceコマンドを使って、以下のようにプロセスI/Oを変更することもできたりますwww
・Real time:システム上のどのような処理に対しても優先して実行する
・Best Effort:デフォルトの設定で、スケジューラに従って実行する
・Idle:システム上のすべての処理に対して後回しに実行する(システムがアイドル状態のときに実行される)
ioniceコマンドは数値が低いものが優先度高いです。。。
2012-12-13
[Java]Swingのコードとかを載せておく
PC内を漁ったら出てきましたよっと
このまま埋もれさせるのもアレなので、貼付けておく。
どこかで何かの役に立つと期待しておく
★List表示の背景色と文字色を変更する
jlistにListCellRendererを設定してやればよい
以下の変更を実施する
・文字色を緑色
・リストで選択した箇所の背景を黒色にする
★ショートカットキーを設定する
メニューをつけたらショートカットキーをつけたいよねってことで以下のキー入力の組み合わせをショートカットキーに設定してみる
・Alt+A
・Ctrl+A
★タブの切り替えを検知する
タブの切り替えを検知して何か処理を行いたいときは
JTabbedPane#addChangeListenerメソッドを実装すればよい
★文字列をOSのクリップボードにコピー
OSの機能のコピーを実現するにはClipboard#setContentsメソッドを使用する
Clipboard#setContentsメソッドの第二引数は、ClipboardOwnerのインスタンスを設定する
こいつは、「クリップボードの内容が他のコピーによって書き換えられたとき」にコールバックされるインスタンスを設定する
必要なければnullでおk
★Byte配列から画像イメージをファイルに出力する
Swing関係ないけど・・・
ImageIOクラスのreadメソッドとwriteメソッドを使えば、ファイルに出力できます
このまま埋もれさせるのもアレなので、貼付けておく。
どこかで何かの役に立つと期待しておく
★List表示の背景色と文字色を変更する
jlistにListCellRendererを設定してやればよい
以下の変更を実施する
・文字色を緑色
・リストで選択した箇所の背景を黒色にする
jList#setCellRenderer(new ListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
String cell = (String) value;
JLabel label = new JLabel();
label.setText(cell);
// 表示文字色の変更
label.setForeground(Color.green);
// リストの選択した部分の色を変更する
if (isSelected) {
label.setOpaque(true); // 背景色を変更するため、不透明にする
label.setBackground(Color.black);
}
return label;
}
});
★ショートカットキーを設定する
メニューをつけたらショートカットキーをつけたいよねってことで以下のキー入力の組み合わせをショートカットキーに設定してみる
・Alt+A
・Ctrl+A
JMenuItem menu = new JMenuItem(); menu.setMnemonic(KeyEvent.VK_A); //Alt+C menu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK));
★タブの切り替えを検知する
タブの切り替えを検知して何か処理を行いたいときは
JTabbedPane#addChangeListenerメソッドを実装すればよい
JTabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
//タブ変更時の処理
}
)};
★文字列をOSのクリップボードにコピー
OSの機能のコピーを実現するにはClipboard#setContentsメソッドを使用する
Clipboard#setContentsメソッドの第二引数は、ClipboardOwnerのインスタンスを設定する
こいつは、「クリップボードの内容が他のコピーによって書き換えられたとき」にコールバックされるインスタンスを設定する
必要なければnullでおk
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection selection = new StringSelection("コピーしたい文字列");
clipboard.setContents(selection, selection);
★Byte配列から画像イメージをファイルに出力する
Swing関係ないけど・・・
ImageIOクラスのreadメソッドとwriteメソッドを使えば、ファイルに出力できます
byte[] bytes = "画像イメージのバイト配列を取得する処理"
BufferedImage image;
try {
image = ImageIO.read(new ByteArrayInputStream(bytes));
ImageIO.write(image, "png", new File("/home/hoge/file.png"));
} catch (IOException e) {
e.printStackTrace();
}
2012-12-12
[Linux]DHCPからIPアドレスを再取得する
使う機会が出たのでメモしておく。
以下のコマンドでDHCPを再取得できます。
・1回目のコマンドで、既に割り振られいたIPアドレスを解放
・2回目のコマンド実行でDHCPサーバーからIPアドレスを再取得
$dhclient eth0
使わないと、ついつい忘れがちですね。
以下のコマンドでDHCPを再取得できます。
・1回目のコマンドで、既に割り振られいたIPアドレスを解放
・2回目のコマンド実行でDHCPサーバーからIPアドレスを再取得
$dhclient -r eth0
$dhclient eth0
使わないと、ついつい忘れがちですね。
[Linux]今更ながらRHEL6のネタ
なんとなく、今更な感じ漂うけど。。。
俺のメモ・・・かな・・・。
・ファイルシステムの変更
1.ext4ファイルシステムが採用
ファイルサイズの上限が16TBのになった(ファイルシステムは、1EB)
ファイルの管理がext3のブロックからブロックをまとめたエクステントに変更された(大容量ファイルの操作に有効)
2.エクステントのプリアローケーション機能によって空ディスク作成時間が短縮された
空のディスクイメージを作成するコマンド
$fallocate -l <ファイルサイズ> disk.img
大容量のファイルシステムの初期化ときにかかるi-nodeの初期化を短縮(バックグラウンドで実行)するコマンド
$mkfs.ext4 -E lazy_itable_init=1 /dev/sda1
3.fsckのコマンドの整合性チェックの時間が短縮された
4.ファイルのタイムスタンプがナノ時間まで記録されるようになった
以下のコマンドで確認することができる
$ls --full-time
もしくは
$stat
・NetworkManagerの追加
ネットワークの切り替え(イーサやワイヤレスといった)を自動化するツールが導入された
固定化してあるネットワークで使用するのであれば起動しておく必要はない(下手に起動しておくとトラブルにつながる可能性)
- 自分は、こいつのおかげでネットワークに接続できなかったトラブルが起きた(うまくつきあえば便利です)
とりあえず停止するコマンド
$chkconfig NetworkManager off
一時的に停止するコマンド
$service NetworkManager stop
NICをNetworkManagerの対象外にするには「/etc/sysconfig/network-scripts/<対象のNIC>」に以下の行を追加する
NM_CONTROLLED=no
ついでにNICとMACアドレスとデバイス名の関係は、「/etc/udev/rules.d/70-persistent-net.rules」に記載されています
NICを交換したときは、このファイルを修正して再起動すれば解消できます。
・dracutによるRAMディスクへの設定変更
RHEL5まであった/etc/modprobe.confが無くなった
- 自分はこれでアレ?ってなった
RHEL6だとデバイスドライバが対応している範囲だと設定が不要らしい
こんな感じで確認できる
$pax -rzf /boot/initramfs-<カーネルバージョン>.img
$lsinitrd /boot/initramfs-<カーネルバージョン>.img
デバイスを追加する場合はdracutコマンドで追加してやればよい
$dracut --add-drivers <ドライバ名>
-H 初期RAM ディスクを作成する
-v デバイスドライバを表示する
-f 初期RAMディスクを上書きする
因みに、mkinitrdコマンドはdracutコマンドのラッパーになったようだ
・デバイスドライバの読み込み
udevを使用している
読み込み順序は以下の感じらしい
1.機器の情報は/sysにマウントされたファイルから参照される
2.参照したデバイスをudevデーモンに通知する
3.modules.aliasに記録された情報を参照して必要なデバイスドライバを読みこんでいる
因みに1で参照する情報は、modalias情報のことベンダーが提供している「ベンダ名」、「製品ID」から独自に構成した文字列です。
modinfoコマンドで確認することができます
・anacronの追加
要するにKVMで立ち上げた仮想マシンがすべて同じタイミングでcronすると物理マシンに負荷が掛かってしまう問題の回避策
実はRHEL5にも搭載されていたらしい(挙動は異なるみたいだけど)
「/etc/anacrontab」を編集すればよい
以下が特徴っぽい(日次、週次、月次を適当なタイミングで実行できるようにする感じに見える)
- ジョブの実行間隔を1日単位で指定
- ランダムな遅延を挿入できる
- デーモンはいないので実行する仕組みを用意する必要がある
・Upstartによる起動処理
従来の起動処理(/etc/inittab)に変わって、イベントベースのジョブ管理に変更された
従来のinittabにずらずら書かれていたジョブを細分化して、起動するランレベルに応じてジョブを実行していくもの
以下の順序で起動シーケンスが実行される
1./sbin/init(startupイベント発行)
2./etc/init/rcS.conf(rcSジョブ起動)
3./etc/init/rc.conf(rcジョブ起動)
ランレベル5以外の場合
4./etc/init/start-ttys.conf(start-ttysジョブ起動)
5./etc/init/tty.congf(ttyジョブ起動)
ランレベル5の場合
4./etc/init/prefdm.conf(prefdmジョブ起動)
Upstartのジョブを作成する場合、「/etc/init」配下に*.confという名前でファイルを作成すればよい
- 作成方法は、rc.confを参考にすればできると思います・・・
start on <ジョブ名>
stop on <ジョブ名>
respwn
exec <処理するスクリプトなど>
・リソース配分のコントロール
プロセスをグループ化してグループ単位でリソース制御をできるようにしている
仮想マシンへのリソース配分もできる(qemu-kvmというプロセスのため)
以下のものに対して設定できる
- CPU(使用時間)
- CPU(コア)
- メモリ
- ブロックIO
・LXCによるコンテナ型仮想技術
複数のユーザー空間を一つ一つのコンテナと見立てて、その中でプロセスを実行するような感じ
サンドボックスにイメージが近いかもしれない
CPUとメモリは共通で使うから
あかん、力つきた・・・
でも、会社だと絶対こんな新機能って使わせてくれないだろうなぁ(遠い目
俺のメモ・・・かな・・・。
・ファイルシステムの変更
1.ext4ファイルシステムが採用
ファイルサイズの上限が16TBのになった(ファイルシステムは、1EB)
ファイルの管理がext3のブロックからブロックをまとめたエクステントに変更された(大容量ファイルの操作に有効)
2.エクステントのプリアローケーション機能によって空ディスク作成時間が短縮された
空のディスクイメージを作成するコマンド
$fallocate -l <ファイルサイズ> disk.img
大容量のファイルシステムの初期化ときにかかるi-nodeの初期化を短縮(バックグラウンドで実行)するコマンド
$mkfs.ext4 -E lazy_itable_init=1 /dev/sda1
3.fsckのコマンドの整合性チェックの時間が短縮された
4.ファイルのタイムスタンプがナノ時間まで記録されるようになった
以下のコマンドで確認することができる
$ls --full-time
もしくは
$stat
・NetworkManagerの追加
ネットワークの切り替え(イーサやワイヤレスといった)を自動化するツールが導入された
固定化してあるネットワークで使用するのであれば起動しておく必要はない(下手に起動しておくとトラブルにつながる可能性)
- 自分は、こいつのおかげでネットワークに接続できなかったトラブルが起きた(うまくつきあえば便利です)
とりあえず停止するコマンド
$chkconfig NetworkManager off
一時的に停止するコマンド
$service NetworkManager stop
NICをNetworkManagerの対象外にするには「/etc/sysconfig/network-scripts/<対象のNIC>」に以下の行を追加する
NM_CONTROLLED=no
ついでにNICとMACアドレスとデバイス名の関係は、「/etc/udev/rules.d/70-persistent-net.rules」に記載されています
NICを交換したときは、このファイルを修正して再起動すれば解消できます。
・dracutによるRAMディスクへの設定変更
RHEL5まであった/etc/modprobe.confが無くなった
- 自分はこれでアレ?ってなった
RHEL6だとデバイスドライバが対応している範囲だと設定が不要らしい
こんな感じで確認できる
$pax -rzf /boot/initramfs-<カーネルバージョン>.img
$lsinitrd /boot/initramfs-<カーネルバージョン>.img
デバイスを追加する場合はdracutコマンドで追加してやればよい
$dracut --add-drivers <ドライバ名>
-H 初期RAM ディスクを作成する
-v デバイスドライバを表示する
-f 初期RAMディスクを上書きする
因みに、mkinitrdコマンドはdracutコマンドのラッパーになったようだ
・デバイスドライバの読み込み
udevを使用している
読み込み順序は以下の感じらしい
1.機器の情報は/sysにマウントされたファイルから参照される
2.参照したデバイスをudevデーモンに通知する
3.modules.aliasに記録された情報を参照して必要なデバイスドライバを読みこんでいる
因みに1で参照する情報は、modalias情報のことベンダーが提供している「ベンダ名」、「製品ID」から独自に構成した文字列です。
modinfoコマンドで確認することができます
・anacronの追加
要するにKVMで立ち上げた仮想マシンがすべて同じタイミングでcronすると物理マシンに負荷が掛かってしまう問題の回避策
実はRHEL5にも搭載されていたらしい(挙動は異なるみたいだけど)
「/etc/anacrontab」を編集すればよい
以下が特徴っぽい(日次、週次、月次を適当なタイミングで実行できるようにする感じに見える)
- ジョブの実行間隔を1日単位で指定
- ランダムな遅延を挿入できる
- デーモンはいないので実行する仕組みを用意する必要がある
・Upstartによる起動処理
従来の起動処理(/etc/inittab)に変わって、イベントベースのジョブ管理に変更された
従来のinittabにずらずら書かれていたジョブを細分化して、起動するランレベルに応じてジョブを実行していくもの
以下の順序で起動シーケンスが実行される
1./sbin/init(startupイベント発行)
2./etc/init/rcS.conf(rcSジョブ起動)
3./etc/init/rc.conf(rcジョブ起動)
ランレベル5以外の場合
4./etc/init/start-ttys.conf(start-ttysジョブ起動)
5./etc/init/tty.congf(ttyジョブ起動)
ランレベル5の場合
4./etc/init/prefdm.conf(prefdmジョブ起動)
Upstartのジョブを作成する場合、「/etc/init」配下に*.confという名前でファイルを作成すればよい
- 作成方法は、rc.confを参考にすればできると思います・・・
start on <ジョブ名>
stop on <ジョブ名>
respwn
exec <処理するスクリプトなど>
・リソース配分のコントロール
プロセスをグループ化してグループ単位でリソース制御をできるようにしている
仮想マシンへのリソース配分もできる(qemu-kvmというプロセスのため)
以下のものに対して設定できる
- CPU(使用時間)
- CPU(コア)
- メモリ
- ブロックIO
・LXCによるコンテナ型仮想技術
複数のユーザー空間を一つ一つのコンテナと見立てて、その中でプロセスを実行するような感じ
サンドボックスにイメージが近いかもしれない
CPUとメモリは共通で使うから
あかん、力つきた・・・
でも、会社だと絶対こんな新機能って使わせてくれないだろうなぁ(遠い目
2012-12-11
[Linux]カーネルコードを修正して使ってみる
小さな変更ですが、こうすればできるという紹介程度ですね。
「起動時にオリジナルのメッセージをログにで出力する」をお題にしましょう。
# 起動やVRAMのメモリとか弄くってもいいのですが、起動しなくなったり不具合が出たりするのでやめておきましょう
▲事前準備
1.ビルドに必要なパッケージ類をインストールする
2.現行のカーネルのソースコードを入手する
以下のサイトで入手できます(バージョン番号を変えると古いものまで入手できます)
http://vault.centos.org/6.3/updates/Source/SPackages/
今回は、「kernel-2.6.32-279.14.1.el6.src.rpm」をダウンロードしました
3.ソースコードの展開を実施
$rmp -ivh kernel-2.6.32-279.14.1.el6.src.rpm
$cd rpmbuild/SPECS
$rpmbuild -bp kernel.spec --target=x86_64
以下のような警告が出るが、無視してもよい
rpmbuild中に処理が固まった場合、以下のコマンドを別のターミナルから実施します
▲ソースコードの修正
1.Makefileの修正
以下のようにオリジナルのバージョンであることを記載する
EXTRAVERSIONに任意の文字列を指定すれば、オリジナルバージョンに変更できます
2.init/main.cの修正
カーネル起動のメッセージから、findとgrepを駆使して探し当てます。
探し当てる方法は、後述しておきます。
__init start_kernel関数に以下の修正を実施します。
# 面白いのは、linux_bannerの配列が定義してあったところに触るんじゃねーってメッセージがあったことですね。
3.ビルドの実施
rpmを作成する場合は以下のコマンドでできます
4.インストール
ビルドしたカーネルを以下のコマンドでインストールする
grubの起動設定で変更したカーネルを使用するように以下のように変更する(defaultの値を変更するぐらいですね)
# rpmのアップデートでインストールする場合、以下のコマンドでできます
5.変更内容の確認
以下のコマンドでカーネルのバージョンがビルドしたものなっているか確認する
以下のコマンドでカーネルの起動メッセージが変更できているか確認する
ついでにソースコードを読んでいくやり方
・検索対象のファイルを限定してから文字列の検索をする
以下のような形でfindコマンドとgrepコマンドを駆使する
$find . -name '*.c'|xargs grep 'main(void)'
・検索する文字列が決まっている場合に検索する
$grep -Hr --binary-files=without-match "main(void)" .
・上記の検索結果からとるべき対処
- 検索結果の内容(メソッドや関数)を丁寧に調べていく
- 呼び出し元を探して処理順序(呼び出しの流れ)を調べていく(文字列なり当たりをつける必要はありますが)
・上記の検索結果から推論を立てて確かめる
あくまで自分の手法なので他にいいやり方があれば教えてくださいm(_ _)m
※今回のネタの場合、カーネルメッセージをfind,grepを駆使して発見しました。
「起動時にオリジナルのメッセージをログにで出力する」をお題にしましょう。
# 起動やVRAMのメモリとか弄くってもいいのですが、起動しなくなったり不具合が出たりするのでやめておきましょう
▲事前準備
1.ビルドに必要なパッケージ類をインストールする
$yum groupinstall "Development Tools" $yum install xmlto asciidoc elfutils-libelf-devel zlib-devel newt-devel python-devel hmaccalc $yum install binutils-devel $yum install perl-ExtUtils-Embed $yum install rng-tools
2.現行のカーネルのソースコードを入手する
以下のサイトで入手できます(バージョン番号を変えると古いものまで入手できます)
http://vault.centos.org/6.3/updates/Source/SPackages/
今回は、「kernel-2.6.32-279.14.1.el6.src.rpm」をダウンロードしました
$wget http://vault.centos.org/6.3/updates/Source/SPackages/kernel-2.6.32-279.14.1.el6.src.rpm
3.ソースコードの展開を実施
$rmp -ivh kernel-2.6.32-279.14.1.el6.src.rpm
$cd rpmbuild/SPECS
$rpmbuild -bp kernel.spec --target=x86_64
以下のような警告が出るが、無視してもよい
警告: ユーザ mockbuild は存在しません - root を使用します 警告: グループ mockbuild は存在しません - root を使用します
rpmbuild中に処理が固まった場合、以下のコマンドを別のターミナルから実施します
$rngd -r /dev/urandom
▲ソースコードの修正
1.Makefileの修正
以下のようにオリジナルのバージョンであることを記載する
EXTRAVERSIONに任意の文字列を指定すれば、オリジナルバージョンに変更できます
VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 32 EXTRAVERSION =-kurobara-custom NAME = Man-Eating Seals of Antiquity RHEL_MAJOR = 6 RHEL_MINOR = 3 RHEL_RELEASE = 278
2.init/main.cの修正
カーネル起動のメッセージから、findとgrepを駆使して探し当てます。
探し当てる方法は、後述しておきます。
__init start_kernel関数に以下の修正を実施します。
boot_cpu_init(); page_address_init(); printk(KERN_NOTICE "%s", linux_banner); printk(KERN_NOTICE "%s", "kurobara's custom kernel"); setup_arch(&command_line); mm_init_owner(&init_mm, &init_task); setup_command_line(command_line);
# 面白いのは、linux_bannerの配列が定義してあったところに触るんじゃねーってメッセージがあったことですね。
3.ビルドの実施
$make -j4
rpmを作成する場合は以下のコマンドでできます
$rpmbuild -ba kernel.spec
4.インストール
ビルドしたカーネルを以下のコマンドでインストールする
$make module_install $make install
grubの起動設定で変更したカーネルを使用するように以下のように変更する(defaultの値を変更するぐらいですね)
default=0 timeout=5 splashimage=(hd0,3)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.32-kurobara-custom) root (hd0,3) kernel /vmlinuz-2.6.32-kurobara-custom ro root=/dev/mapper/vg_paruonet-lv_root rd_NO_LUKS rd_LVM_LV=vg_paruonet/lv_swap rd_NO_MD crashkernel=auto LANG=ja_JP.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us rd_LVM_LV=vg_paruonet/lv_root rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-kurobara-custom.img
# rpmのアップデートでインストールする場合、以下のコマンドでできます
$rpm -Uvh --force <作成したカーネルのrpmファイル>
5.変更内容の確認
以下のコマンドでカーネルのバージョンがビルドしたものなっているか確認する
$uname -a
以下のコマンドでカーネルの起動メッセージが変更できているか確認する
$dmesg |less
ついでにソースコードを読んでいくやり方
・検索対象のファイルを限定してから文字列の検索をする
以下のような形でfindコマンドとgrepコマンドを駆使する
$find . -name '*.c'|xargs grep 'main(void)'
・検索する文字列が決まっている場合に検索する
$grep -Hr --binary-files=without-match "main(void)" .
・上記の検索結果からとるべき対処
- 検索結果の内容(メソッドや関数)を丁寧に調べていく
- 呼び出し元を探して処理順序(呼び出しの流れ)を調べていく(文字列なり当たりをつける必要はありますが)
・上記の検索結果から推論を立てて確かめる
あくまで自分の手法なので他にいいやり方があれば教えてくださいm(_ _)m
※今回のネタの場合、カーネルメッセージをfind,grepを駆使して発見しました。
2012-12-10
[Linux]tar.bz2ファイルの圧縮と展開
簡単だけど、あまり使わないので忘れてしまいがちなのでメモしておく
tar.bz2ファイルを圧縮する場合
tar.bz2ファイルを展開する場合
tar.bz2ファイルを圧縮する場合
$tar -jcvf 圧縮後ファイル名.tar.bz2 圧縮前ファイル名
tar.bz2ファイルを展開する場合
$tar -xjvf 解凍(展開)するファイル名.tar.bz2
[Tomcat]mod_jkのバグにやられる
填められましたよ。ええ。
こんな感じの環境でCGIを動作させようとしてました 。
・Apache 2.x
・Tomcat 6.x
・mod_jk 1.2.28
・perl 5.8
所謂、普通のLAMP構成ですな。。。
でもね、以下の条件が揃ったときに発動するバグがあるんですよ。。。
・mod_jkのバージョンが1.2.28
・mod_jk.confにJkWatchdogIntervalを設定している
・Apache上でCGIと併用して使用する
この条件が揃ったときに何が起こるかというと・・・
「Apacheがhang-upする」
もうちょっと正確にすると、こんな感じの図の状態になってしまいます。
<----------正常動作---------><-----hang-up----->
↑ ↑
apache起動 JkWatchdogInterval発動
正直、運用してたりすると笑えないです。。。
# オチがバグかよということで、笑い話になってましたけどね。
対処は2つのパターンかなーとか
・mod_jkのバージョンアップ
・JkWatchdogIntervalをコメントアウト(使わないようにする)
因に、mod_jkの1.2.27の「JkWatchdogInterval」のバグがあります。
こっちは設定する単位を間違えていて、microsecとmillisecを間違えているというwww
# こっちは、上の図と同じ挙動で10分も反応がなくなりますwww-----hang-up----->---------->
こんな感じの環境でCGIを動作させようとしてました 。
・Apache 2.x
・Tomcat 6.x
・mod_jk 1.2.28
・perl 5.8
所謂、普通のLAMP構成ですな。。。
でもね、以下の条件が揃ったときに発動するバグがあるんですよ。。。
・mod_jkのバージョンが1.2.28
・mod_jk.confにJkWatchdogIntervalを設定している
・Apache上でCGIと併用して使用する
この条件が揃ったときに何が起こるかというと・・・
「Apacheがhang-upする」
もうちょっと正確にすると、こんな感じの図の状態になってしまいます。
<----------正常動作---------><-----hang-up----->
↑ ↑
apache起動 JkWatchdogInterval発動
正直、運用してたりすると笑えないです。。。
# オチがバグかよということで、笑い話になってましたけどね。
対処は2つのパターンかなーとか
・mod_jkのバージョンアップ
・JkWatchdogIntervalをコメントアウト(使わないようにする)
因に、mod_jkの1.2.27の「JkWatchdogInterval」のバグがあります。
こっちは設定する単位を間違えていて、microsecとmillisecを間違えているというwww
# こっちは、上の図と同じ挙動で10分も反応がなくなりますwww-----hang-up----->---------->
2012-12-09
[Linux]Linuxのキーバインドを変更する
自分が知ってる範囲ですが、やり方は以下の2種類あります
・キーテーブルファイルを変更する方法
・xmodmapとxenvを組み合わせる方法
両方書いておきます。。。
実は、いずれの方法でもxenvは使いますけどねwww
★キーテーブルファイルを変更する方法
1.キーボードの動作タイプを「/etc/sysconfig/keybord」のファイルを開いて確認する
以下のような形で出力されます。
・KEYBOARDTYPEは、参照しているキーボードのタイプを意味しています
・KEYTABLEは、参照しているキーテーブルファイル名を表してます
2.1の結果からキーテーブルファイルを編集する(1の場合、「/lib/kbd/keymap/i386/qwerty/jp106.map.gz」がキーテーブルファイル)
- このときxenvを使用してキーコードを調べてく
-以下のコマンドを使用して変更内容を用意する
3.再起動する
★xmodmapを組み合わせて変更する方法
1.現在の設定を確認しておく
$xmodmap -pke
2.設定を書き出す
$xmodmap -pke > .xmodmap
3.xenvで変更したいキーコードを確認する
4.2で書き出したファイルに設定を変更する
Caps LockのキーをCtrlに変更したい場合は、以下のような感じにする(xenvを起動してCapsLockをおして確認しておく)
・「keycode 66 = Eisu_toggle Caps_Lock Eisu_toggle Caps_Lock」を「keycode 66 = Control_L NoSymbol Control_L」に変更
5.キーバインドの変更を反映する
$xmodmap .xmodmap
両方やっておけば、確実に設定内容は反映されますね。。。
他にやり方があれば、どなたか教えてくださいm(_ _)m
・キーテーブルファイルを変更する方法
・xmodmapとxenvを組み合わせる方法
両方書いておきます。。。
実は、いずれの方法でもxenvは使いますけどねwww
★キーテーブルファイルを変更する方法
1.キーボードの動作タイプを「/etc/sysconfig/keybord」のファイルを開いて確認する
以下のような形で出力されます。
・KEYBOARDTYPEは、参照しているキーボードのタイプを意味しています
・KEYTABLEは、参照しているキーテーブルファイル名を表してます
KEYBOARDTYPE="pc" KEYTABLE="jp106"
2.1の結果からキーテーブルファイルを編集する(1の場合、「/lib/kbd/keymap/i386/qwerty/jp106.map.gz」がキーテーブルファイル)
- このときxenvを使用してキーコードを調べてく
-以下のコマンドを使用して変更内容を用意する
$gzip -d jp106.map.gz $vi jp106.map $gzip jp106.map
3.再起動する
★xmodmapを組み合わせて変更する方法
1.現在の設定を確認しておく
$xmodmap -pke
2.設定を書き出す
$xmodmap -pke > .xmodmap
3.xenvで変更したいキーコードを確認する
4.2で書き出したファイルに設定を変更する
Caps LockのキーをCtrlに変更したい場合は、以下のような感じにする(xenvを起動してCapsLockをおして確認しておく)
・「keycode 66 = Eisu_toggle Caps_Lock Eisu_toggle Caps_Lock」を「keycode 66 = Control_L NoSymbol Control_L」に変更
5.キーバインドの変更を反映する
$xmodmap .xmodmap
両方やっておけば、確実に設定内容は反映されますね。。。
他にやり方があれば、どなたか教えてくださいm(_ _)m
登録:
投稿 (Atom)