恥は/dev/nullへ by 初心者

プログラミング素人がのろのろと学んだことをつづっています♪

Debian環境設定(4) /etc/apt/sources.list の設定

この記事は、主にDebian Administrator's Handbookを眺めて書いたものです。
対象はDebian 10 (buster)です。

 

  

Part 1 : Debian Administrator's Handbook

Debian Administrator's Handbookのサイト

 ダウンロードページ

 

 

Part 2 : 用語

APT

APTは Advanced Package Tool の略だそうです。

 

ソースパッケージとパッケージソース

ソースパッケージ(source package)は、ソースコードのパッケージ。
パッケージソース(package source)は、パッケージのあるリポジトリ

 

 

Part 3 : /etc/apt/sources.listの説明

APTを使うにはリポジトリの一覧を /etc/apt/sources.list に記述しておく必要があります。 

<記述例>
deb http://ftp.riken.jp/Linux/debian/debian buster main contrib non-free
deb-src http://ftp.riken.jp/Linux/debian/debian buster main contrib non-free

ベースリポジトリ以外も記述したフル設定の例はPart4の「stable版向けの設定例」をご覧ください。

 

記述例のとおり、sources.listファイルの各行は、少なくとも3つのフィールドから構成されています。

なお、フィールドとはスペースで区切られた項目のことです。記述例の1行目において、1つ目のフィールドは「deb」で、2つ目のフィールドは「http://ftp.riken.jp/Linux/debian/debian」です。

 

1番目のフィールド

1番目のフィールドはパッケージのタイプを表しています。

deb      バイナリーパッケージ(バイナリファイルの入ったパッケージ)
deb-src  ソースパッケージ(ソースコードの入ったパッケージ)

  

2番目のフィールド

2番目のフィールドはリポジトリのURLです。
記述例ではインターネット上のリポジトリになっていますが、以下のようにCD-ROM等をリポジトリに指定することもできます。

http:// Webサーバー上のリポジトリhttps:// で始まる場合もあります。)
ftp://  FTPサーバー上のリポジトリ (ftps:// で始まる場合もあります。)
file:// PC上のリポジトリ
cdrom:  CD_ROM、DVD-ROM、Blu-rayディスク

 

3番目のフィールド

3番目のフィールドは、指定するリポジトリの構造によって記述の仕方が異なります。
ハンドブックによると、サブディレクトリが無いリポジトリなら「./」を指定することもできるそうですが、大抵のポジトリは階層構造になっています。

 

(比較) リポジトリの構成とsources.listの記述

理化学研究所リポジトリを見ると、Debian 10 (buster) のある場所は以下のとおりです。

http://ftp.riken.jp/Linux/debian/debian/dists/buster/

そして、このbusterディレクトリの中に「main」ディレクトリ、「contrib」ディレクトリ、「non-free」ディレクトリがあります。

 

このリポジトリを利用する場合、sources.listには以下のように記述します。

deb http://ftp.riken.jp/Linux/debian/debian buster main contrib non-free

理化学研究所のURLにある「dists」ディレクトリを記述する必要は無いようです。

 

3番目のフィールドは、Debianコードネーム版(stable、 testing、 unstable等)です。コードネームで記述する場合、Debian 10 のコードネームは busterなので、次のようになります。

deb http://ftp.riken.jp/Linux/debian/debian buster main contrib non-free

 

版で既述する場合、次のようになります(stable版を指定した場合)。

deb http://ftp.riken.jp/Linux/debian/debian stable main contrib non-free

 

 

Part 4 : /etc/apt/sources.listの設定例

(追記)Debian12用のsources.listの設定例は以下の記事のとおりです。

/etc/apt/sources.list(Debian12) - 恥は/dev/nullへ by 初心者

 

Debian10(buster)用の設定例

# Security updates
deb http://security.debian.org/ buster/updates main contrib non-free
deb-src http://security.debian.org/ buster/updates main contrib non-free

# Base repository
deb http://ftp.riken.jp/Linux/debian/debian buster main contrib non-free
deb-src http://ftp.riken.jp/Linux/debian/debian buster main contrib non-free

# Stable updates
deb http://ftp.riken.jp/Linux/debian/debian buster-updates main contrib non-free
deb-src http://ftp.riken.jp/Linux/debian/debian buster-updates main contrib non-free

# Stable backports
deb http://ftp.riken.jp/Linux/debian/debian buster-backports main contrib non-free
deb-src http://ftp.riken.jp/Linux/debian/debian buster-backports main contrib non-free

 

上の例では「Security updates」を除き、理研リポジトリを指定しています(Security updatesはミラーサイトには無いため)。


余談ですが、念のためsecurity.debian.orgを調べました。
http://security.debian.org/dists/buster/updates/ の中に「main」「contrib」「non-free」がありました。

 

リポジトリに含まれるパッケージ

大抵のパッケージはベースリポジトリから取得します。ベースリポジトリには全てのパッケージが含まれているものの、更新頻度は少なめで2ヶ月に1回くらいのポイントリリース(バグフィックス等)です。

それ以外のリポジトリ部分的なもので、全てのパッケージが含まれているわけではありません(ただ、新しいバージョンのパッケージを提供するらしいです)。

 

非公式のリポジトリは最後に記述する

欲しいバージョンのパッケージが複数のリポジトリにある場合、aptは(sources.list内で)最初に記述されているリポジトリを利用します。よって、非公式のリポジトリはsources.listの最後に記述します。

 

Security updatesリポジトリ

Debianで使用されているソフトに脆弱性などがあると分かると、それを修正するためのセキュリティアップデートが提供されます。
これを拾ってくるために「Security updates」に記述したリポジトリを使用します(このアップデートはミラーサイトにはありません)。

 

Stable updatesリポジトリ

Stable updatesリポジトリは、主に重大なバグに対するバグフィクスを提供します。なお、stable版のポイントリリース(ベースリポジトリのポイントリリース)よりも早くアップデートを提供してくれるそうです。

 

Stable backportsリポジトリ

Stable backportsリポジトリには package backports があります(package backportsとは、古いディストリビューション(通常はstable版)向けに再コンパイルした最近のソフトのパッケージだそうです)。しかし、意図的に指定しないとaptはpackage backportsをインストールしてくれません。

 

ハンドブックには以下の2つの方法が記載されていました。

$ sudo apt-get install パッケージ名/buster-backports
$ sudo apt-get install -t buster-backports パッケージ名

 

main, non-free, contrib

パッケージがどのようなライセンスに従っているかに応じて、「main」、「non-free」、「contrib」に分かれているらしいです。

  • mainは、DFSG(Debian Free Software Guidelines)に準拠しているもの。
  • non-freeは、DFSGに完全には準拠していないが、制約なしに配布することができるもの(公式にはDebianではない)。
  • contribは、オープンソースだがnon-freeなものを必要とするパッケージ。

 

(補足)
contribの説明に登場するnon-freeなものの例として、ハンドブックには次の例が挙げられています。
・ゲームのROM、コンソールのBIOS
コンパイルするのにプロプライエタリなソフトを必要とするもの

LinuxのGUI環境(X Window System、ディスプレイマネージャ、ウィンドウマネージャ、デスクトップ環境)

今までテキトーに使っていたので、少し真面目にLinuxGUI環境に関する知識を整理してみました。この記事の構成は以下のとおりです。

 

 

 

Part 1 : X Window System

X Window Systemとは?

X Window Systemを簡単に言うと、グラフィカルな環境を提供するためのクライアントサーバー型のシステムです。このシステムでは、X11というプロトコルがクライアントとサーバーの通信に使われます。なお、このシステムにおけるサーバーをXサーバーといい、クライアントをXクライアントと言います。

 

このうち、Xクライアントは、ブラウザやエディタ等、個々のソフトです。Xサーバーは、各Xクライアント間の調整やユーザー側とXクライアントの仲介をするものです。


たとえば、ユーザーがキーボードで文字を入力するとエディタに文字が表示されますね。この時、キーボードからの入力を受け取るのはXサーバーです。Xサーバーは受け取った入力内容を(X11プロトコルを使って)Xクライアントであるエディタに伝えます。すると、エディタ上に文字が表示されます。

 

今の例だと「キーボード  →  Xサーバー  →  Xクライアント」という一方向の説明にしかなっていないので少し補足します。「エディタに文字が表示される」のは、エディタがXサーバーに対して「(ユーザーが見ている)画面にこれを表示してください」と依頼しているからです。つまり、「Xクライアント  →  Xサーバー  →  画面」という処理も行われているということです。

 

X Window Systemに関する用語

ネット上を見ると、X Window Systemに関する用語は結構アバウトに使われています。

 

たとえば、「X11をインストールする」という表現を普通に見かけます。しかし、用語に注意を払って記述されている文書を読むと、X11とはXプロトコルのバージョン11であると説明されています。これを前提にすると、先の表現は「Xプロトコルのバージョン11を実装したX Window Systemをインストールする」と書いた方がいいのかもしれません。

 

でも、表現が無駄に長くなっただけのような気がしなくもありません・・・^^;。
個人的には、文章の読み手に誤解を与えなければ「X11をインストールする」でも良いと思います。


という個人的な意見を述べた上で、調べたことを以下に記します。

 

「X」

単に X とだけ書かれている場合、以下の可能性がありそうです。
X Window System(X というウィンドウシステム)を指している。
・Xサーバーを指している。
・Xというプロトコルを指している(専門的な文書でなければ、この可能性は低そう)。


X11

X11はXプロトコルのバージョン11を指す言葉です。XサーバーとXクライアントはこのプロトコルを使って通信します。

しかし、「X11を実装したX Window System」や「X11を実装したXサーバー」の意味でも使われているようです。

 

このプロトコルに関する文書
https://www.x.org/releases/current/doc/xproto/x11protocol.html


「Xlib」

アプリケーションやツールキットが利用する、Xプロトコルを実装したクライアント用ライブラリのこと。


「Xサーバー」

X Window Systemにおいて、接続しているXクライアント間の調整や、ユーザー側とXクライアントの仲介を担う仕組み(またはその実装)。


Xorg

オープンソースで実装されたXサーバーです。
Xorg(Xの次は小文字のオー)は現在主流のXサーバーでX.Org(Xの次はドットと大文字のオー)によって開発されています。
  

X Window Systemの名前の由来

X Window Systemの名前の由来が以下のPDFに書かれていました。
https://apps.hci.rwth-aachen.de/borchers-old/cs377a/materials/p79-scheifler.pdf

このPDFによると、かつて W Window Systemというものがあったらしく、X Window Systemの階層的な仕組みはW Window Systemから来ているそうです。W Window Systemの「W」に対する言葉として(アルファベット順でWの次の)「X」になったようです。

 

 

Part 2 : ディスプレイマネージャ

ディスプレイマネージャとは?

ディスプレイマネージャは、グラフィカルなログイン画面を提供するソフトです。
Linuxを起動すると、通常はコンソールでログイン画面が表示されますが、ディスプレイマネージャを利用するとグラフィカルなログイン画面が表示されます。

 

メジャーなディスプレイマネージャ

ネット上の記事でよく見かけるものとしては、XDM、GDMKDMなどがあります。

ただ、XDMについてビミョーに気になることがあります。X11 R7.6のmanページにはxdmの記載があるのですが、X11 R7.7のmanページにはxdmの記載がないんですよね。はて?

 

SLiMについて

SLiMというディスプレイマネージャもそこそこ有名なのですが、ArchLinuxのWikiを読むと「SliM プロジェクトは活動を停止しています (プロジェクトのホームページ に繋がらない状態となっており、github のミラー も動きがありません)。また、logind セッションなど、SLiM は systemd に完全には対応していません。他のディスプレイマネージャや Xinitrc を使うようにしてください。」と書かれています。

 活動を停止しているとなると、仮にセキュリティホールが見つかっても対応されないと思いますので、使わない方が良さそうです。

 

 

Part 3 : ウィンドウマネージャ

ウィンドウマネージャとは?

ウィンドウマネージャは、グラフィカルな画面に表示されているウィンドウの管理(サイズ変更、移動、削除など)を担うものです(ここでいうウィンドウとは、画面上にある各ソフトを指しています)。

 

そもそも、X Window Systemはグラフィカルな表示機能を提供しますが、それだけしかしません。表示された個々のウィンドウをマウスで移動したり、サイズを変更したりする機能は提供しないのです。この部分を担当しているのがウィンドウマネージャです。

 

この点に関しては、次の記事が非常に分かりやすいです(必読!)。
https://qiita.com/ai56go/items/1b8bfeede2b467ac0667

 

古いですが、次のページも参考になります。読みものとしても面白いです。

https://linuxjf.osdn.jp/JFdocs/XWindow-Overview-HOWTO/window-managers.html
このページによると、ウィンドウマネージャっていうのは『メタクライアント』だ。その一番基本的な 任務は他のクライアントを管理することなんだ。」とのことです。

なお、このページは、X Window Systemアーキテクチャをざっくり説明する文書の一部です。

 

メジャーなウィンドウマネージャ

Linuxで使えるウィンドウマネージャは沢山ありますので、以下のページをご覧ください。

ウィンドウマネージャ一覧
このページはArchLinux関連のページですが、Linuxで使える様々なウィンドウマネージャが並んでいるので便利です。また、スタック型のウィンドウマネージャとタイル型のウィンドウマネージャに関する説明もあります。

 

 

Part 4 : デスクトップ環境

デスクトップ環境を明確に説明するのは難しいですが、ざっくり言えば、必要なソフトが一通りそろっていて、マウス操作で便利に使えるようになっている環境です。たとえば、WindowsMacBookのデスクトップ画面をイメージしてもらえば良いかなと思います。

 

Windowsのようにマウス操作であれこれできるようになっていますので、当然ですがデスクトップ環境にはウィンドウマネージャ(の機能)も含まれています。

 

Linuxのデスクトップ環境としては昔からGNOMEKDEが有名です。

この2大勢力のほかにも、XfceEnlightenmentなど様々なデスクトップ環境があります。

 

  

Part 5 : 参考にしたページ

X Window System関係

EXPLANATIONS
個人的にイチオシX Window Systemについて学ぶのにとても良いページです。用語に注意を払って文章を書いている点も良かったです。なお、後ろの方にコードも登場します。

私は、以下の3つのパートだけを読みました。
・BASIC ARCHITECTURE
・REQUESTS AND EVENTS
・LET'S GO


ウィキペディアの「X Window System」の項目
日本語で読めますし、ざっくりとした理解をするには良いかなと思います。XサーバーとXクライアントの図が分かりやすいです。


KENスクールブログの記事
説明が簡潔で分かりやすいです。ディスプレイマネージャ、ウィンドウマネージャ等の説明もあります。

 

サルでも分かるX11入門
タイトル通り、読みやすいです。

ディスプレイマネージャ関係

Linux - Display Manager
ディスプレイマネージャからX Window Systemが起動する流れだけでなく、X Window Systemに関する設定ファイルの説明も書かれている点が良いです。

 

ディスプレイマネージャの種類

Linuxが起動してからディスプレイマネージャが実行されるまでのシーケンスが簡単に書かれています。

 

ディスプレイマネージャの概要

ディスプレイマネージャ経由でX Window Systemが起動するまでの流れが少し詳しく書かれています。

 

このページによると、コンソールでLinuxシステムにログインする際は、init、getty、loginが水面下で仕事をしているそうですが、ディスプレイマネージャはグラフィカルな画面でこの3つに相当する役割を果たしているそうです。

 

initLinux上で最初に実行されるプログラムで、起動時に各種スクリプトを実行したり、gettyを起動したりします。


gettyについては良く分かりません。manページによると「ttyポートを開いて、ログインネームの入力を促し、loguinコマンドを実行する」そうです。

 

(追記)

gettyに関して以下の2つのページを見つけました。チラ見したところ何となく参考になりそうなので、後で読んでみます。

 

 

 

<さりげなくDebian関係のリンク>

XWindowSystem - Debian Wiki

このページにある各種リンクが役立ちそうです。まずは「Xorg」と「Xinitrc」から。

 

DisplayManager - Debian Wiki

GNOMEKDEを使う予定は無いので、LightDMにしようかなと思っています。

 

DesktopEnvironment - Debian Wiki

タイトルはDesktopEnvironmentですがウィンドウマネージャ等の記載もあります。

Debian環境設定(3) 起動時にNumLockをONにする

コンソール画面でテンキーを使ったら数字が入力されなかったので、NumLockがOFFになっていることに気づきました。そこで、NumLockをONにする方法を調べました。

 

 

環境

Debian 10 (buster)on VirtualBox 6.1.6

 

setledsコマンド

ネット情報によると、以下のコマンドが使えそうです。

setleds

manページを読むと、このコマンドは、NumLockキー、CapsLockキー、Scrollキーの挙動を設定するものでした。
NumLockをONにする場合は、以下のようにします。

setleds +num

毎回コマンドを実行するのは面倒なので、このコマンドをホームディレクトリの.profileに記述しました。
実験がてら一度ログアウトして再ログインしたらNumLockがONになっていました。解決です。

 

-Dオプション

manには、 -D オプションについて以下の説明があります。

With option -D, setleds will change both the VT flags and their default settings (so that a subsequent reset will not undo the change). This might be useful for people who always want to have numlock set.

これが正しければ、-D オプションを付けてsetledsを実行することによりデフォルト設定が変更されるはずです。
そこで、rootユーザーでログインし直して、

setleds -D +num

を実行してみました。

しかし、ログアウトしてから再ログインするとNumLockがONになっていませんでした。この点がやや謎ですが、.profileにコマンドを記述しておけば実用上の問題は無いので、深く考えないことにしました^^;。

 

manページの説明(一部抜粋)

Name
setleds - set the keyboard leds

 

Synopsis
setleds [-v] [-L] [-D] [-F] [{+|-}num] [{+|-}caps] [{+|-}scroll]

 

Description
Setleds reports and changes the led flag settings of a VT (namely NumLock, CapsLock and ScrollLock). Without arguments, setleds prints the current settings. With arguments, it sets or clears the indicated flags (and leaves the others unchanged). The settings before and after the change are reported if the -v flag is given.

 

(中略)

 

Options
-num +num
Clear or set NumLock. (At present, the NumLock setting influences the interpretation of keypad keys. Pressing the NumLock key complements the NumLock setting.)

 

-caps +caps
Clear or set CapsLock. (At present, the CapsLock setting complements the Shift key when applied to letters. Pressing the CapsLock key complements the CapsLock setting.)

 

-scroll +scroll
Clear or set ScrollLock. (At present, pressing the ScrollLock key (or ^S/^Q) stops/starts console output.)

 

 

X Window起動時にNumLockをONにする方法

X Window起動時にNumLockをONにする手順については以下の記事のとおりです。

https://uhoho.hatenablog.jp/entry/2021/09/01/025630

Debian環境設定(2) キーボードレイアウトを変更する

記号を入力しようとしたら、自分が意図したものとは違った記号が画面に表示されました。キーボードの設定がおかしいようです。そこで、キーボードレイアウトの設定を変更しました。

 

環境

Debian10 (buster)  on VirtualBox6.1.6
キーボードは REALFORCE A / R2A-US3-BK

 

問題点

Debianをインストールする時、ロケール設定をJapan / Japanese にしたので、キーボードレイアウトの設定がJIS配列(日本語配列)となっています。しかし、自分が使っているキーボードはUS配列(英語配列)です。
よって、US配列キーボードに適した設定に変更する必要があります。

 

設定ファイル

ネット情報によると、キーボードレイアウトを設定しているファイルは

/etc/default/keyboard

らしいです。

このファイルの中にある次の2行を変更しました。

XKBMODEL
XKBLAYOUT

 

変更後は以下のとおりです。

XKBMODEL="pc105"
XKBLAYOUT="us"

 

(追記)US配列のMacBookで使う場合は以下の設定で動作しました。

XKBMODEL="macbook79"

XKBLAYOUT="us"

  

スクリーンショット

 /etc/default/keyboard の中身

f:id:philojuan:20201220070507p:plain

 

Debian環境設定(1) 名前解決の問題

前置き

近年はMacBookUbuntuを使っていたため(インストール後、そのまま使えてしまうため)、最近のLinuxの設定知識がビミョーです。
そこで、Debian 10(buster)を最小構成でインストールして、勉強しつつ環境作りをしています。

 

名前解決ができていない?

必要なソフトをインストールしようとしてapt-get install を実行しましたが、上手く行きませんでした。
そこで、ネットワークの接続状況を調べてみました。

ping -c 2 8.8.8.8

としてみると応答があったので、ネットには接続できているようです。
しかし、、、

ping -c 2 dns.google

としてみると「ping: dns.google: Temporary failure in name resolution」となってしまいました。

以上のことから、名前解決ができていないと分かりました。

 

/etc/resolv.confとDHCP

名前解決に関するファイルとしては、/etc/hostsや/etc/resolv.confがありますね。
/etc/hosts には問題がなかったので、/etc/resolv.conf を開いてみました。

nameserver 192.168.10.1

となっています。自宅のルーターを指しているので問題なさそうです。
しかし、この設定で名前解決ができていないので、これをGoogleDNSに変更してみました。

nameserver 8.8.8.8

にしてみると、無事に名前解決ができました。
これでaptコマンドが使えるようになったので、manやsudoなどをインストールしました。

 

しかし、Debian再起動すると /etc/resolv.confの内容が元に戻ってしまいます。

インストール時点でネットワークの設定をしていないので、DHCPでネット接続しているはずです。とすれば、DHCPがこのファイルを書き換えているものと思います。

 

/etc/network/interfacesを修正(DHCPを無効にする)

/etc/network/interfacesを開いてみると、次の行が目に留まりました。

allow-hotplug enp0s3
iface enp0s3 inet dhcp

この2行のうち、2行目をコメントアウトして、代わりにstaticなアドレスを割り当てることにしました。

 

そこで、

man interfaces

を実行して斜め読みしてみたら、以下の記述がありました。

f:id:philojuan:20201217174255p:plain


この記述を読んで /etc/network/interfaces の一部を以下のように修正しました。

allow-hotplug enp0s3
auto enp0s3           ← この行を忘れずに追記

# iface enp0s3 inet dhcp

iface enp0s3 inet static
    address   192.168.10.7
    netmask   255.255.255.0
    broadcast 192.168.10.255
    gateway   192.168.10.1

これでDHCPによるresolv.confの書き換えは起きないはずです。

 

ひとまず解決

再起動してから /etc/resolv.conf を開くと

nameserver 8.8.8.8

となっていて、DHCPによる書き換えは起きていませんでした。

ping -c 2 dns.google

を実行してみると無事に応答がありました。

 

課題(DHCPの設定)

DHCPによる割り当てが上手く行っていないことが気になります。
ネットワーク以外の環境を整えてから、この問題に取り組もうと思います。

 

他に使ったコマンド

systemctl status networking.service
service networking restart

2つ目はネットワーク関係のinitスクリプトを実行させるためのものです。
これにより /etc/init.d/networking スクリプトが実行されます。

 

任意のローソク足のvolume値が、過去N本のvolume値の上位 X番目までにランクインしているか調べてみる

任意の足のvolume値が、過去N本のvolume値の上位 X番目までにランクインしているか調べる関数を書いてみました。ただ、これは依頼されて作った関数なので、私は使用していません^^;。(関数のコードは本記事の末尾にあります)

 

関数が行っていること

 a本目のローソク足から過去N本の範囲の出来高(volume)を調べます。
その範囲の上位X番目のvolume値と指定したローソク足pのvolume値を比較します。
指定したローソク足pのvolume値が、上位X番目のvolume値以上ならtrueを返します。

WithinTopXvolume(p, a, N, X)

 

具体例

 2本目のローソク足出来高(volume)が、「3本目から過去10本(3本目~12本目)の出来高のうち、上位5番目」までにランクインしているか調べる場合、引数は以下のようになります。

WithinTopXvolume(2, 3, 10, 5)

 

戻り値

ランクインしている場合は true を返します。
ランクインしていない場合は false を返します。

 

備考

チャート上に存在しない足を検索対象として指定した場合、上述の調査をしない
で処理を中止します。この時、関数はfalseを返し、アラートを出します。
アラートが出た場合の戻り値 falseは、「調査を実行できなかった」という意味のfalseです。

チャート上に存在しない足を検索対象にしないという観点で言えば、第1引数~第3引数は「0以上」でなくてはなりません。

それと、ランキングの先頭は1番目という前提で以下のコードは書かれているので、第4引数は「1以上」でなくてはなりません。

 

コード

//------------------------------------------------------------------------------
// 任意のローソク足のvolume値が、過去N本のvolume値の上位 X番目以内か調べる関数
//------------------------------------------------------------------------------
// [この関数が行っていること]
// a本目のローソク足から過去N本の範囲の出来高(volume)を調べる。
// その範囲の上位X番目のvolume値と指定したローソク足のvolume値を比較する。
// 指定したローソク足のvolume値が、上位X番目のvolume値以上ならtrueを返す。
//
// [使用例]
// 2本目のローソク足出来高(volume)が、「3本目から過去10本(3本目~12本目)
// の出来高のうち、上位5番目」までにランクインしているか調べる場合、引数は
// 以下のとおり。
//
//     WithinTopXvolume(2, 3, 10, 5)
//
// [戻り値]
// ランクインしている場合は true を返す。
// ランクインしていない場合は false を返す。
//
// [備考]
// チャート上に存在しない足を検索対象として指定した場合、上述の調査をしない
// で処理を中止する。この時、関数はfalseを返し、アラートを出す。
// アラートが出た場合、「調査を実行できなかった」という意味でfalse。
//------------------------------------------------------------------------------

bool WithinTopXvolume(int targetShift,    // 対象とする足のシフト
                      int startShift,     // 範囲の開始シフト
                      int bars,           // 範囲(開始シフトを含めてN本)
                      int rank)           // 範囲の上位 X 番目
{
    //-----------------------------------------------------------------------------
    // チャート上に存在しない足を検索対象にした場合、処理を中止してアラートを出す
    //-----------------------------------------------------------------------------
    if(Bars - 1 < startShift + bars - 1) {    // 左辺と右辺の「-1」は無くてもOK
        Alert("Function Error [WithinTopXvolume] : Read the message on Expert.");
        printf("Function Error [WithinTopXvolume] : You tried to access the candle out of range.");
        return(false);
    }

    bool res = false; // 関数の戻り値
    int counter = 0;  // 配列操作用のカウンタ

    long array[];              // iVolume関数の戻り値がlong型なので配列もlong型
    ArrayResize(array, bars);  // 配列の要素数をセット

    // 指定したシフトから過去bars本の出来高を配列に格納
    for(int k = startShift; k < startShift + bars; k++) {
        array[counter] = iVolume(NULL, PERIOD_CURRENT, k);
        counter++;
    }

    //-----------------------------------------------------------------------------
    // 配列内に同じ値が2つ以上あったら、1つは残し、残りは最小値に書き換える
    //-----------------------------------------------------------------------------
    // 最初に配列の中身を降順で並び替えておく
    ArraySort(array, WHOLE_ARRAY, 0, MODE_DESCEND);

    // 配列内の最小値をminValueに格納
    // (降順ソート済なので long minValue = array[bars - 1] でも可)
    long minValue = array[ArrayMinimum(array, WHOLE_ARRAY, 0)];

    long tmp = array[0];            // 配列の先頭要素の値をtmpに代入

    for(int j = 1; j < bars; j++) {
        // 要素の値が最小値と同じならループを抜ける(無駄な処理を減らす)
        if(array[j] == minValue) break;

        // 要素の値がtmpと同じなら、その要素をminValueに書き換える
        if(tmp == array[j]) {
            array[j] = minValue;
        }
        // 要素の値がtmpと違うなら、tmpにその要素の値を代入する
        else {
            tmp = array[j];
        }
    }

    ArraySort(array, WHOLE_ARRAY, 0, MODE_DESCEND);  // 改めて降順で並び替え

    // 比較対象とするローソク足のvolume値をtargetValueに格納
    long targetValue = iVolume(NULL, PERIOD_CURRENT, targetShift);

    // targetValueが上位X番目のvolume値以上ならresにtrueを代入
    if(targetValue >= array[rank - 1])
    {
        res = true;
    }

    return res;
}

 

 追記

この記事を書き終えてから思ったのですが・・・。

for(int j = 1; j < bars; j++) {

この行の「bars」のところは「bars - 1」の方が良かったですね。

降順に並び替えた後なので、配列の最終要素は最小値です。
だから、配列の最終要素に対しては何の処理も不要ですね。

「R」起動時の処理を記述するファイル (.Rprofile)

(前置き)この記事において、ホームディレクトリは /home/juan/ です。

 

Rを起動した時点では、ホームディレクトリにいる状態です。
R用に「R_space」ディレクトリを作成したので、そこを作業ディレクトリにしようと思いました。

 

そこで、作業ディレクトリを指定するsetwdコマンドを使いました。

> setwd("/home/juan/R_space")

 

しかし、Rを再起動してgetwdコマンドを実行すると、作業ディレクトリがホームディレクトリに戻ってしまっています。(備考:getwdコマンドは作業ディレクトリの場所を表示するコマンド。)

 

これではRを使うたびにsetwdで作業ディレクトリを指定しなければならなくて不便です。普通に考えて初期化処理を行う方法があるはずだと思ったのでネット検索をしてみました。

 

以下のページによると、「.Rprofile」というファイルを作れば、初期化処理ができるようです。
https://stats.biopapyrus.jp/r/devel/rprofile.html

 

そこで、ホームディレクトリに.Rprofileファイルを作成し、

setwd("/home/juan/R_space")

と記述しました。

 

そして、Rを再起動して

> getwd()

を実行しました。

 

実行結果は以下のとおりで、「R_space」が作業ディレクトリとなっていました。

[1] "/home/juan/R_space"

 

無事解決です^^。