让我们搭建一个与电脑将棋软件对战的服务器<第一部分>
我想在一个小时前我可能还在玩电脑围棋,但是现在要转而玩电脑将棋软件。
要件定義
-
- URL叩いたら指し手を返してほしい。1秒以内で。
-
- 環境
レンタルサーバーは用意される
Linux
なるほど……、最近どんな騒ぎがあったのか知らないのかツッコミたいところだが わたしには関係ない。
让我们想一想
まず わたしの環境なんだが
- Windows 10
我想到的是
-
- 浮かむ瀬
-
- Ubuntu ※第4回電王トーナメントでも大人気だ。USBに入れて突きさしてセットアップされる。
(追記)(初期インストール済み) 14.04.5 LTS (GNU/Linux 3.13.0-63-generic x86_64)
GCC g++-4.8以上
teratarm PuTTY
(追記) mono ※将棋所を使う場合
(追記) FileZilla
(追記)(初期インストール済み) nano ※テキストエディター
(追記)(初期インストール済み) bash ※シェル・スクリプト
但是我感觉可能需要搭建一个 Web 服务器。
-
- Apache
- PHP
があればいいんだろうか? 将棋ソフトって マルチユーザーに対応しているのか?キューとか要るんじゃないか?とりあえず1人用でいいか。
ローカル環境でテストもしたいし、Windows上でLinux を動かすバーチャルなあれなんて名前だったか……。思い出せないや、ググって出てくる バーチャルボックスを調べておこう。
让我们建立一个测试环境。
まず ローカルに テスト環境を構築しよう。
あとで記事を続ける。
Windows 10 で Virtual Box を導入できるだろうか。ググって読んでおこう。
参考文献: 《在Windows操作系统上使用VirtualBox来运行Linux(Ubuntu)的步骤和设置》(我的开发研究所)http://itmemo.net-luck.com/virtualbox-ubuntu/
先提前下載一下《浮かむ瀬》的源檔,以防萬一。
请参考以下内容:「第4届将棋电脑王比赛 版本(适用于Windows 64位)(参赛软件名称:浮かむ瀬)」(Apery)
(开放源码将应每)http://hiraokatakuya.github.io/apery/
BIOS无法启动
Antec の CORE i3 なんだが、[F2][F10][F12][F8][Del] で BIOS が出てこなかった。
USBポートを左上の方に挿してみて [Del][F6] もやってみたが BIOS は出てこなかった。
我再进一步调查一下。
我无法建立本地测试环境。
如果没有,就没有……。
顺便说一下,我从来没有见过我家开发电脑的BIOS。
查看为期2周的预设的一个台桜VPS物理服务器免费服务的网页。
http://vps.sakura.ad.jp/
标准操作系统是“Ubuntu14.04 amd64 / Ubuntu16.04 amd64”吗?那么已经安装了Ubuntu,对吧?
计算机与安全
总的来说,计算机的发展是朝着限制使用的方向发展,而不是无限制地使用。这是因为人类并不像超有机体的盖亚理论那样,而是像一个群体生物,每个个体都自私地使用资源……。
所以,使用計算機資源的人需要創設用戶帳戶。直譯的話,這個日文詞彙的意思大概是關於金錢出入的地方,類似於銀行帳戶之類的概念,但是account也包含了count這個詞彙,而且前綴ac-似乎有“往某個方向”的意思。
用户帐户已经准备好了。可以说是容易理解的。
-
- ネットワーク上の住所 (IPアドレス)
-
- その住所にあるコンピュータ内で使われる自分の氏名 (ユーザー名)
- 本人確認をするもの (パスワード)
如果能记住这三点,就可以进入电脑(登录)并发送文件(数据)。
就像进入家里一样,可以确保发送的包裹能够到达。
そういえば ログ というのは足跡のようなもので、いつコンピューター(家)に入ったかとか、コンピューターに入って何をしたかとか、最後にファイルを開いたのは誰か、とか残されていくんだが、コンピューターに入ることを ログイン と呼ぶのも興味深い。
そういえばルート・ユーザーというのがあったな
Teratarm という寺さんが作ったターミナルでログインしようかと思ったんだが、(へぇ、今はコミュニティが開発を後継しているのか)
開発PCのランチャーに PuTTY のアイコンがあったので PuTTY で接続してしまった。
接続プロトコルのタイプは SSH だ。なんかセキュリティーが高いんだろうぐらいしか分からないが「SSHだ」と言われたら SSH を選ぶしかない。こっちが好きなものを選べます、というやつじゃない。
PuTTYがなんかセキュリティ警告を出しているが気にせず [はい(Y)] を選んで入る。
ユーザー名に root と入れてパスワード叩いて Linux に入れね、とか思ってたんだが 聞いてみると ルート・ユーザーでは入れないらしい。
そういえばなんか su コマンドとかあった気もする。Windows 10 だって 自分のアカウントで入ってから右クリックして「管理者権限で実行」を選んだりもする。
不要再说我有Linux实际工作经验了,完全不行。
命令行
我只记得一点点,但您很暴躁。
请切换到超级用户(root)权限。
他告诉我一个命令,所以我试着使用它。
因为被要求输入密码,所以我输入了密码。
现在好像已经变成了root用户。因此权限会变得更大,可能会有所帮助。
ls
敲击。一无所获。
ls -an
と叩く。
. で始まる名前のファイルがいっぱい出てくる。隠しファイルばっかりか。
フォルダーや、隠しじゃないファイルは無いようだ。
mkdir shogi
随便创建一个文件夹试试看。
ls -an
将shogi文件夹没了。
这是哪里呢?
cd ../
哇,我找不到它在哪里了。我以为它在主文件夹,但有些奇怪。它是不是在根文件夹里?
cd root
ls
嗯……。原来有将棋文件夹啊。
在这种叫 root 的我搞不清楚的地方,是不需要文件夹的。我把它删掉吧……。
rmdir shogi/
ls
好的。
应该在哪里部署将棋软件(即使它可以立即使用),像是在搬家时将纸箱送到新居并打开箱子一样,将所有的事情都做完吗?
“了解不同目录的功能(根目录篇)(1/2)” (@ IT)
http://www.atmarkit.co.jp/ait/articles/0108/07/news002.html
将将棋软件放入bin目录中,感觉不太像一个命令。它的功能似乎很庞大,
而且我也不确定是否可以放置从外部频繁使用的东西在root文件夹中,
也不太觉得它像是一个可以共享的软件。
那么,也许可以放在etc目录中。但它不是一个配置文件……。
那就安全地回家吧。
在home目录下,有一个以自己账户名命名的文件夹,进一步进入该文件夹。
权限
文件传输失败了,它告诉我很生气。原来在Linux上有权限这个东西!
ls -an
drwxr-xr-x ~略~ 01:37 shogi
权限(设置文件的访问范围)是在目录d中,分别为rwx、r-x、r-x。
r表示读取、w表示写入、x表示执行,-表示没有权限。
以上是这三个权限的组合是什么来着。
「第2回『权限的含义和用法区分』」(MdN Design Interactive)
http://www.mdn.co.jp/di/articles/2104/?page=2
据说「所有者」「群组」「其他」这三个都排列在一起。群组之类的我从来没用过。
嗯,如果我打算从外部传输文件,是不是应该给「其他」添加写入权限 w 呢?
chmod 757 shogi/
ls -an
drwxr-xrwx ~略~ 01:37 shogi
~
ここが変わった
好的,没问题。
让我们进行文件传输吧
FileZilla を使って Windows 10 から Linux へ Apery を転送しよう。
那个?日语的抽象度好奇怪哦。再来一遍。
ファイル転送ソフトを使って Windows から Linux へコンピュータ将棋ソフトを転送しよう。
好的。
具体来说,
FileZilla を使って Windows 10 から Ubuntu へ 浮かむ瀬 を転送する。
好的。
如果不能区分日语中的抽象性和具体性,有时候在对话中对方会像超级马里奥在峡谷跌落后突然跳出来那样做出反应。
当然,我没有那样的口语能力。
啊,对了对了。要从服务器上注销登录。
exit
logout
必须要连续两次敲击才行。(*2017年3月6日补充:似乎从服务器上退出,然后从PuTTY中退出。通过连续敲击exit命令就可以。)
我有事出门了。回来后会继续写文章。
继续。
当您登录后查看页面时
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-63-generic x86_64)
* Documentation: https://help.ubuntu.com/
New release '16.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
写着这样的字。
do-release-upgrade
如果我输入 “y” 会怎么样呢?会要求输入密码,然后需要输入 [yN]。
不管它怎么写,就当它说的是把端口号设为’1022’,我们不予理会,继续进行。
在里面写着更新需要几个小时……如果是这样的话,我在外出之前应该先更新好的……。
一想到这个问题,就经常被问到并且无法离开电脑。
还看到了“系统将重新启动”的字样,但系统并没有重新启动的迹象。
似乎是连接超时导致断开了连接。
重新连接后,消息已经改变了。
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Sat Mar 4 20:59:46 2017 from ~略~
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
那么,现在更新工作已经完成了吗?
sudo su -
输入密码,切换到root用户。
cd ../
ls
cd home
ls
cd アカウント名
ls
cd shogi
ls
apery-SDT4.tar.gz apery-SDT4.zip
嗯。一方是源代码,另一方是二进制文件。
这两个都不是来源吗?我不是很清楚。
能解压tar.gz文件吗?
解压命令似乎没有安装或者路径没有配置正确。
apt install unzip
我试试这个命令。这次似乎可以执行 unzip 命令了。
End-of-central-directory ~略~
看起来收到了某种错误消息。那就试试解压.zip的文件。似乎有些动静。
ls
apery-SDT4 ~以下略~
造了一个apery-SDT4的文件夹吗?
(Note: The original text does not appear to be in Chinese. The provided paraphrase assumes that “apery-SDT4” refers to the name of a directory created.)
cd apery-SDT4
ls
bin Copying.txt Readme.txt src utils
这个源代码是否已经解压了?是否无法编译这个源代码?
让我们来了解一下g++4.8以上是什么意思。
使用g++编译
「g++」(C++)
http://kaworu.jpn.org/cpp/g++
这个名字有点复杂……。
首先,在Ubuntu系统上搜索是否安装了g++。
从上述网站获取。
apt-cache search g++
用鼠标拖动以复制,并在PuTTY上右键粘贴。
出现了很多文字并且它们不断流动,我不知道是什么原因。
在Ubuntu上安装g++
(Translation: Install g++ on Ubuntu)
我要立刻跳到最新的版本上去。
sudo apt install g++-4.9
安装完成了吗?试试输入命令。
g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
你已经安装好了g++吧?
試著將Apery的源代碼編譯成可執行的形式
我认为C语言将编译过程写入Makefile,但g++呢?
「Makefile的编写方式」(Web求职日记)
看来,apery-SDT4/src/目录下的Makefile似乎与浮かむ瀬存在关联。
cd apery-SDT4/src/
切换当前目录至包含Makefile的目录。
gmake
No command 'gmake' found, did you mean:
~略~
是不是不一样呢……。
man -k g++
太多的命令以至于搞不清楚了。
「自动化GNU Make入门课程 – Makefile基础:规则文档」(オブラブ)
http://objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/gnu-make/rule.html
make
有点动起来了。
看一下输出的一部分。
g++ -o apery ../obj/main.o ../obj/bitboard.o ../obj/init.o ../obj/mt64bit.o ../o
bj/position.o ../obj/evalList.o ../obj/move.o ../obj/movePicker.o ../obj/square.
o ../obj/usi.o ../obj/generateMoves.o ../obj/evaluate.o ../obj/search.o ../obj/h
and.o ../obj/tt.o ../obj/timeManager.o ../obj/book.o ../obj/benchmark.o ../obj/t
hread.o ../obj/common.o ../obj/pieceScore.o -lpthread -std=c++11 -fno-exception
s -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp
因为写着这句话,所以可以推断在上一层目录的obj文件夹内应该有中间文件(.o)创建好了。顺便问一下,在Linux中可以用什么来替代.exe文件呢?是命令吗?
翠黄色的仿制品
嗯?
ls
apery evaluate.cpp move.hpp search.hpp
benchmark.cpp evaluate.hpp movePicker.cpp square.cpp
benchmark.hpp generateMoves.cpp movePicker.hpp square.hpp
benchmark.sfen generateMoves.hpp mt64bit.cpp thread.cpp
bitboard.cpp hand.cpp mt64bit.hpp thread.hpp
bitboard.hpp hand.hpp overloadEnumOperators.hpp timeManager.cpp
book.cpp ifdef.hpp piece.hpp timeManager.hpp
book.hpp init.cpp pieceScore.cpp tt.cpp
color.hpp init.hpp pieceScore.hpp tt.hpp
common.cpp learner.hpp position.cpp usi.cpp
common.hpp main.cpp position.hpp usi.hpp
evalList.cpp Makefile score.hpp
evalList.hpp move.cpp search.cpp
在列表的开头,apery,嗯,不是文件夹,而是可执行文件吗?
ls -an
-rwxr-xr-x 1 0 0 444728 Mar 4 22:16 apery
给了 x 权限。能不能执行呢?
apery
apery: command not found
为什么会有问题呢……。
创建一个类似“ls”的命令 (Magenta工作室)
http://www.mm2d.net/main/prog/linux/ls-08.html
难道不是一个可执行文件吗……。
「我是Ubuntu的新手,想在终端上执行程序。」
./apery
噢,好像处理没有回应被阻塞了。如果在后台运行会怎样呢?
让程序强制结束
按下【Ctrl】+【C】,它不就停下来了吗?已停止。
让程序在后台运行
那么,要在后台运行怎么办?
【Linux】在后台运行作业(丨维基百科)
http://zh.wikipedia.org/wiki/Background%20job
如果Qiita能把从Qiita到Qiita的文章链接变得像WordPress一样酷炫的话,那就太好了wwwww听说在命令的末尾加上&就可以了。
./apery &
[1] 1692
哦。
请在Apery中使用标准输入输入
那么,我能和apery说话吗?例如,和牛之类的。
“图解:标准输入、标准输出、标准错误输出、管道是什么?” (Linux)
http://www.creatology.jp/unix/outin.html
echo 'usi' > ./apery
-su: ./apery: Text file busy
違うのか。
「(2−5)複数のコマンド間で標準入出力を共有し,連携するためには,パイプを用いる。」 (Linux上でシェルが実行される仕組みを,体系的に理解しよう (bash 中級者への道))
那我们试着用管道(垂直竿)连接一下。
echo 'usi' | ./apery
id name Apery Debug Build
id author Hiraoka Takuya
option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Draw_Ply type spin default 256 min 1 max 2147483647
option name Engine_Name type string default Apery Debug Build
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
option name Move_Overhead type spin default 30 min 0 max 5000
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Slow_Mover type spin default 89 min 1 max 1000
option name Slow_Mover_10 type spin default 10 min 1 max 1000
option name Slow_Mover_16 type spin default 20 min 1 max 1000
option name Slow_Mover_20 type spin default 40 min 1 max 1000
option name Threads type spin default 2 min 1 max 256
option name Time_Margin type spin default 4500 min 0 max 2147483647
option name USI_Hash type spin default 256 min 1 max 1048576
option name USI_Ponder type check default true
usiok
哇!能和Apery聊天啦!
デバッグ・ビルド と リリース・ビルド
但是,请稍等一下。
id name Apery Debug Build
我很在意。这是不是以调试模式编译的应用程序呢?
我要找出以非调试模式编译的方法……。
当查看apery-SDT4的usi.cpp时,
#ifdef NDEBUG
(*this)["Engine_Name"] = USIOption("ukamuse_SDT4");
#else
(*this)["Engine_Name"] = USIOption("Apery Debug Build");
#endif
在Makefile文件中可以指定NDEBUG这个预处理器宏,我认为只要指定了它,就可以变成ukamuse_SDT4了。
-DNDEBUG
という記述を よく見かける。 -D と NDEBUG なのだろう。どうやって利用するのか?
「如何编写Makefile」(网页求职日记)
那么,这样吧。
make bmi2
make CFLAGS='-std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopen
mp -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -ma
vx2' LDFLAGS='-lpthread -flto' apery
make[1]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
make[1]: 'apery' is up to date.
make[1]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
嗯,发生了什么事情呢?
停止后台进程
顺便提一下,Apery Debug Build你一直在后台运行着。
「【停止】停止后台作业」(ITPro)
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230891/
%1692
-su: fg: %1692: no such job
哎呀。
jobs
[1]+ Stopped ./apery
什么时候停下来的呢?
ファイルを削除してもう一回 make すると?
rm apery
ls
好的。
make bmi2
make CFLAGS='-std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopen
mp -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -ma
vx2' LDFLAGS='-lpthread -flto' apery
make[1]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
g++ -o apery ../obj/main.o ../obj/bitboard.o ../obj/init.o ../obj/mt64bit.o ../o
bj/position.o ../obj/evalList.o ../obj/move.o ../obj/movePicker.o ../obj/square.
o ../obj/usi.o ../obj/generateMoves.o ../obj/evaluate.o ../obj/search.o ../obj/h
and.o ../obj/tt.o ../obj/timeManager.o ../obj/book.o ../obj/benchmark.o ../obj/t
hread.o ../obj/common.o ../obj/pieceScore.o -lpthread -flto -std=c++11 -fno-exc
eptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -DNDEBUG -DHAVE_SSE4 -DHAVE_S
SE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2
make[1]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
ls
好的。重新做一遍。
echo 'usi' | ./apery
id name Apery Debug Build
这不行吗哈哈哈哈
make publish
~中略~
echo 'usi' | ./apery
id name ukamuse_SDT4
这样行吗?不过跑分开始后花费的时间太长了。或者是为了优化而故意让它执行吗?
我們來打掃一下
尝试进行第二次发布时
Illegal instruction
被说了这样的话就会停下来。
make clean
只要这样做就可以了吗?
cd ..
ls obj
objディレクトリの中を空っぽにしてくれたみたいだ。
make publish
よし、またコンパイルが走り出した。
イリーガル インストラクション
./apery
Illegal instruction
事情往往不会朝着顺利的方向发展。
把 apery 移动到 bin 文件夹里,怎么样?
mv apery ../bin/apery
ls
ls ../bin
apery
好的。
../bin/apery
Illegal instruction
果真是在某个地方损坏了吗?或者是没有评价文件呢?
生成文件 和 运行命令 make publish
うん? Makefile に何か書いてるぞ。
#CFLAGS += -march=native # make publish の時はここをコメントアウトする必要がある。
你这是在用注释啊,头上有个 # 标志着呢。
make publish
make profgen
make[1]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
make CFLAGS='-std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov' LDFLAGS='-lpthread -fprofile-generate -lgcov' bmi2
make[2]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
make CFLAGS='-std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2' LDFLAGS='-lpthread -fprofile-generate -lgcov -flto' apery
make[3]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/main.o -c main.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/bitboard.o -c bitboard.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/init.o -c init.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/mt64bit.o -c mt64bit.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/position.o -c position.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/evalList.o -c evalList.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/move.o -c move.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/movePicker.o -c movePicker.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/square.o -c square.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/usi.o -c usi.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/generateMoves.o -c generateMoves.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/evaluate.o -c evaluate.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/search.o -c search.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/hand.o -c hand.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/tt.o -c tt.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/timeManager.o -c timeManager.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/book.o -c book.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/benchmark.o -c benchmark.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/thread.o -c thread.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/common.o -c common.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2 -o ../obj/pieceScore.o -c pieceScore.cpp
g++ -o apery ../obj/main.o ../obj/bitboard.o ../obj/init.o ../obj/mt64bit.o ../obj/position.o ../obj/evalList.o ../obj/move.o ../obj/movePicker.o ../obj/square.o ../obj/usi.o ../obj/generateMoves.o ../obj/evaluate.o ../obj/search.o ../obj/hand.o ../obj/tt.o ../obj/timeManager.o ../obj/book.o ../obj/benchmark.o ../obj/thread.o ../obj/common.o ../obj/pieceScore.o -lpthread -fprofile-generate -lgcov -flto -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2
make[3]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
make[2]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
make[1]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
Makefile:86: recipe for target 'publish' failed
make: *** [publish] Illegal instruction
那么,
make clean
make profgen_sse
这次是否成功编译了吗?
ls
~略~
echo 'usi' | ./apery
id name ukamuse_SDT4
id author Hiraoka Takuya
option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Draw_Ply type spin default 256 min 1 max 2147483647
option name Engine_Name type string default ukamuse_SDT4
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
option name Move_Overhead type spin default 30 min 0 max 5000
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Slow_Mover type spin default 89 min 1 max 1000
option name Slow_Mover_10 type spin default 10 min 1 max 1000
option name Slow_Mover_16 type spin default 20 min 1 max 1000
option name Slow_Mover_20 type spin default 40 min 1 max 1000
option name Threads type spin default 2 min 1 max 256
option name Time_Margin type spin default 4500 min 0 max 2147483647
option name USI_Hash type spin default 256 min 1 max 1048576
option name USI_Ponder type check default true
usiok
よし!
我们来进行一次基准测试。
./apery &
[3] 2508
在那个时候,我似乎正在尝试复制粘贴,然后按下了 [Ctrl] + [C],感觉导致了进程的中断。
我需要重新开始。
./apery &
[4] 2511
在PuTTY中,只需使用鼠标拖动即可复制。
使用左键单击即可粘贴。
echo 'bench' | ./apery
[4]+ Stopped ./apery
嗯,这不是正确的用法吗?
./apery bench
Killed
这个也不对。
ソースコードを読んでいるんだが、そういや、きふわらぷりーを作っているとき、.exe と一緒のフォルダーに benchmark.sfen ファイルが無かったら落ちてたなあ。
ls
apery evaluate.cpp move.hpp search.hpp
benchmark.cpp evaluate.hpp movePicker.cpp square.cpp
benchmark.hpp generateMoves.cpp movePicker.hpp square.hpp
benchmark.sfen generateMoves.hpp mt64bit.cpp thread.cpp
bitboard.cpp hand.cpp mt64bit.hpp thread.hpp
bitboard.hpp hand.hpp overloadEnumOperators.hpp timeManager.cpp
book.cpp ifdef.hpp piece.hpp timeManager.hpp
book.hpp init.cpp pieceScore.cpp tt.cpp
color.hpp init.hpp pieceScore.hpp tt.hpp
common.cpp learner.hpp position.cpp usi.cpp
common.hpp main.cpp position.hpp usi.hpp
evalList.cpp Makefile score.hpp
evalList.hpp move.cpp search.cpp
好的,那就将apery和benchmark.sfen文件放入bin文件夹中,应该就可以了吧?
mv apery ../bin/apery
mv benchmark.sfen ../bin/benchmark.sfen
ls ../bin
apery benchmark.sfen
请问这样可以吗?
../bin/apery bench
Killed
这是不行的吗?
../bin/apery bench &
[5] 2571
[1] Stopped ./apery
[2] Stopped ./apery
[3]- Stopped ./apery
[4]+ Stopped ./apery
[5] Killed ../bin/apery bench
「杀死」和「阻止」有什么不同之处呢?
きふわらぷりーで bench
大樹の枝を改悪した きふわらぷりー だと、まず Kifuwarapery.exe をダブルクリックしてコマンドプロンプトを出し、
しばらく待って入力できる状態になってから bench と入力して[Enter]キーを押すとベンチマークが走り出す。
我觉得可能也是一样的情况……。
./apery
之后,毫不犹豫地就会变成被杀掉的状态,不是吗?
在aper的main.cpp文件中,有一个名为main的函数。
// 将棋を指すソフト
int main(int argc, char* argv[]) {
initTable();
Position::initZobrist();
HuffmanCodedPos::init();
auto s = std::unique_ptr<Searcher>(new Searcher);
s->init();
s->doUSICommandLoop(argc, argv);
s->threads.exit();
}
なので、 コマンド・ループで止まっていてくれると思うんだが……、調べてみるか。
void Searcher::doUSICommandLoop(int argc, char* argv[]) {
bool evalTableIsRead = false;
Position pos(DefaultStartPositionSFEN, threads.main(), thisptr);
std::string cmd;
std::string token;
for (int i = 1; i < argc; ++i)
cmd += std::string(argv[i]) + " ";
do {
if (argc == 1 && !std::getline(std::cin, cmd))
cmd = "quit";
std::istringstream ssCmd(cmd);
ssCmd >> std::skipws >> token;
if (token == "quit" || token == "stop" || token == "ponderhit" || token == "gameover") {
if (token != "ponderhit" || signals.stopOnPonderHit) {
signals.stop = true;
threads.main()->startSearching(true);
}
else
limits.ponder = false;
if (token == "ponderhit" && limits.moveTime != 0)
limits.moveTime += timeManager.elapsed();
}
else if (token == "go" ) go(pos, ssCmd);
else if (token == "position" ) setPosition(pos, ssCmd);
else if (token == "usinewgame"); // isready で準備は出来たので、対局開始時に特にする事はない。
else if (token == "usi" ) SYNCCOUT << "id name " << std::string(options["Engine_Name"])
<< "\nid author Hiraoka Takuya"
<< "\n" << options
<< "\nusiok" << SYNCENDL;
else if (token == "isready" ) { // 対局開始前の準備。
tt.clear();
threads.main()->previousScore = ScoreInfinite;
if (!evalTableIsRead) {
// 一時オブジェクトを生成して Evaluator::init() を呼んだ直後にオブジェクトを破棄する。
// 評価関数の次元下げをしたデータを格納する分のメモリが無駄な為、
std::unique_ptr<Evaluator>(new Evaluator)->init(Evaluator::evalDir, true);
evalTableIsRead = true;
}
SYNCCOUT << "readyok" << SYNCENDL;
}
else if (token == "setoption") setOption(ssCmd);
else if (token == "write_eval") { // 対局で使う為の評価関数バイナリをファイルに書き出す。
if (!evalTableIsRead)
std::unique_ptr<Evaluator>(new Evaluator)->init(Evaluator::evalDir, true);
Evaluator::writeSynthesized(Evaluator::evalDir);
}
#if defined LEARN
else if (token == "l" ) {
auto learner = std::unique_ptr<Learner>(new Learner);
learner->learn(pos, ssCmd);
}
else if (token == "make_teacher") {
if (!evalTableIsRead) {
std::unique_ptr<Evaluator>(new Evaluator)->init(Evaluator::evalDir, true);
evalTableIsRead = true;
}
make_teacher(ssCmd);
}
else if (token == "use_teacher") {
if (!evalTableIsRead) {
std::unique_ptr<Evaluator>(new Evaluator)->init(Evaluator::evalDir, true);
evalTableIsRead = true;
}
use_teacher(pos, ssCmd);
}
else if (token == "check_teacher") {
check_teacher(ssCmd);
}
else if (token == "print" ) printEvalTable(SQ88, f_gold + SQ78, f_gold, false);
#endif
#if !defined MINIMUL
// 以下、デバッグ用
else if (token == "bench" ) {
if (!evalTableIsRead) {
std::unique_ptr<Evaluator>(new Evaluator)->init(Evaluator::evalDir, true);
evalTableIsRead = true;
}
benchmark(pos);
}
else if (token == "key" ) SYNCCOUT << pos.getKey() << SYNCENDL;
else if (token == "tosfen" ) SYNCCOUT << pos.toSFEN() << SYNCENDL;
else if (token == "eval" ) std::cout << evaluateUnUseDiff(pos) / FVScale << std::endl;
else if (token == "d" ) pos.print();
else if (token == "s" ) measureGenerateMoves(pos);
else if (token == "t" ) std::cout << pos.mateMoveIn1Ply().toCSA() << std::endl;
else if (token == "b" ) makeBook(pos, ssCmd);
#endif
else SYNCCOUT << "unknown command: " << cmd << SYNCENDL;
} while (token != "quit" && argc == 1);
threads.main()->waitForSearchFinished();
}
うーむ。Windowsの実行と、Linuxの実行に違いはあるのだろうか。
Makefile:86: recipe for target 'publish' failed
make: *** [publish] Killed
嗯,最近“Killed”经常出现呢。
jobs
[1] Stopped ./apery
[2] Stopped ./apery
[3] Stopped ./apery
[4] Stopped ./apery
[5]- Stopped ./apery (wd: /home/csg10/shogi/apery-SDT4/bin)
[6]+ Stopped ./apery (wd: /home/csg10/shogi/apery-SDT4/bin)
这个停下来的堆积是好事吗?
试着使用kill命令-
「バックグラウンドプロセス(ジョブ)の管理Add Star」 (satake7’s memo)
http://d.hatena.ne.jp/satake7/20080606/p1
这样对吗?
kill %1
jobs
[1] Terminated ./apery
[2] Stopped ./apery
[3] Stopped ./apery
[4] Stopped ./apery
[5]- Stopped ./apery (wd: /home/csg10/shogi/apery-SDT4/bin)
[6]+ Stopped ./apery (wd: /home/csg10/shogi/apery-SDT4/bin)
Stopped が Terminated に変わったが、なんのこっちゃ。
この調子で全部のジョブをkillした。
jobs
make clean
make publish
不行吗。
SSE2的教授生成器
make clean
make profgen_sse2
make CFLAGS='-std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov' LDFLAGS='-lpthread -fprofile-generate -lgcov' sse2
make[1]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
make CFLAGS='-std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2' LDFLAGS='-lpthread -fprofile-generate -lgcov -flto' apery
make[2]: Entering directory '/home/csg10/shogi/apery-SDT4/src'
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/main.o -c main.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/bitboard.o -c bitboard.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/init.o -c init.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/mt64bit.o -c mt64bit.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/position.o -c position.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/evalList.o -c evalList.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/move.o -c move.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/movePicker.o -c movePicker.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/square.o -c square.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/usi.o -c usi.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/generateMoves.o -c generateMoves.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/evaluate.o -c evaluate.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/search.o -c search.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/hand.o -c hand.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/tt.o -c tt.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/timeManager.o -c timeManager.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/book.o -c book.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/benchmark.o -c benchmark.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/thread.o -c thread.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/common.o -c common.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2 -o ../obj/pieceScore.o -c pieceScore.cpp
g++ -o apery ../obj/main.o ../obj/bitboard.o ../obj/init.o ../obj/mt64bit.o ../obj/position.o ../obj/evalList.o ../obj/move.o ../obj/movePicker.o ../obj/square.o ../obj/usi.o ../obj/generateMoves.o ../obj/evaluate.o ../obj/search.o ../obj/hand.o ../obj/tt.o ../obj/timeManager.o ../obj/book.o ../obj/benchmark.o ../obj/thread.o ../obj/common.o ../obj/pieceScore.o -lpthread -fprofile-generate -lgcov -flto -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -fprofile-generate -lgcov -DNDEBUG -DHAVE_SSE2 -msse2
make[2]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
make[1]: Leaving directory '/home/csg10/shogi/apery-SDT4/src'
这不是很顺利吗?
./apery &
[1] 3144
jobs
[1]+ Stopped ./apery
不行吗?
./apery bench
info string start setting eval table
info string end setting eval table
なんのこっちゃ。今までよりは 反応があるだけマシか。
どうも、メインループからすぐ抜けてしまうのか、Stopped になってしまうようだ。
評価関数ファイルが無いんじゃないか?
让我们来调查一下,奇妙的机器是如何运作的……。
创建一个类似于 make_synthesized_eval.sh 的文件,编写成 .bat 格式,然后在 20151105 文件夹中生成三个二进制文件 KPP_synthesized.bin、KK_synthesized.bin 和 KKP_synthesized.bin。
我們來查一查吧。
ukamuse_sdt4.zip 的中文释义是英国互动文化娱乐公司_sdt4 的压缩文件。
似乎还有一个名为 ukamuse_sdt4.zip 的二进制文件。这是什么东西?让我们使用 FileZilla 将其传输到 Linux 服务器并尝试解压缩。
unzip ukamuse_sdt4.zip
膨脹:
膨脹︰
製造︰
製造︰一些出現,但是不知道是什麼。
あら、ukamuse_sdt4 にも src が入っている。
ls
20161007 ukamuse_sdt4_bmi2.exe ukamuse_sdt4_sse2.exe ukamuse_sdt4_sse41.exe ukamuse_sdt4_sse42.exe
そして .bin の中には exe も入っているが、Linux で使うのだろうか?
20161007 フォルダーの中には
ls
KKP_synthesized.bin KPP_synthesized.bin log_v1.10.0.txt log_v1.1.1.txt log_v1.13.0.txt log_v1.2.0_2.txt log_v1.3.0.txt log_v1.5.0.txt log_v1.7.0.txt
KK_synthesized.bin log_v1.0.3.txt log_v1.11.0.txt log_v1.12.0.txt log_v1.14.0.txt log_v1.2.0.txt log_v1.4.0.txt log_v1.6.0.txt log_v1.8.1.txt
と、いろいろ入っている。じゃあ ukamuse_sdt4 フォルダーの中で Linux用にコンパイルし直したらいいのだろうか?
那么,就在src目录中。
make publish
~中略~
Makefile:86: recipe for target 'publish' failed
make: *** [publish] Illegal instruction
我觉得CPU可能不支持。
make clean
make profgen_sse2
这样的话编译就能通过了。
mv apery ../bin/apery
ls
20161007 apery ukamuse_sdt4_bmi2.exe ukamuse_sdt4_sse2.exe ukamuse_sdt4_sse41.exe ukamuse_sdt4_sse42.exe
这个怎么样?
./apery
よし、ループでブロック(ループを抜けない)されてる感じがする。[Ctrl]+[C]で抜ける。
./apery bench
数秒でループを抜けたようだ。よく分からない。
./apery
暂时等待一下。
没有发生任何事情。
./apery &
[1] 3459
jobs
[1]+ Stopped ./apery
不行吗。
以下のコードが含まれています。
src/evaluate.cpp文件中包含以下代码。
std::string Evaluator::evalDir = "20161007";
因为写的是这样,所以文件夹名应该是正确的。
那么接下来在 src 目录中。
cp benchmark.sfen ../bin/benchmark.sfen
执行。
啊,长椅子动了。
./apery bench
这一次轮到 bench 执行。对于测试用例,读取的走法一次又一次地排列。
info depth 16 seldepth 37 multipv 1 score cp -562 upperbound nodes 1866534 nps 206978 time 9018 pv 6g6h+ 5h4i 6h6g S*5b 3a4b 5b4c+ 4b4c 6f6e 6g5g 6e7d B*6g 4i3h 6g5f+ 7d6d 5g4g 3h2g 2b5e R*5a
info nodes 1950370 time 9518
bestmove 6g6h+ ponder 5h4i
那么对局怎么样?
./apery usi &
[2] 3510
id name ukamuse_SDT4
id author Hiraoka Takuya
option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Draw_Ply type spin default 256 min 1 max 2147483647
option name Engine_Name type string default ukamuse_SDT4
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
option name Move_Overhead type spin default 30 min 0 max 5000
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Slow_Mover type spin default 89 min 1 max 1000
option name Slow_Mover_10 type spin default 10 min 1 max 1000
option name Slow_Mover_16 type spin default 20 min 1 max 1000
option name Slow_Mover_20 type spin default 40 min 1 max 1000
option name Threads type spin default 2 min 1 max 256
option name Time_Margin type spin default 4500 min 0 max 2147483647
option name USI_Hash type spin default 256 min 1 max 1048576
option name USI_Ponder type check default true
usiok
jobs
[1]+ Stopped ./apery
[2]- Done ./apery usi
jobs
[1]+ Stopped ./apery
我还没完成……我希望你能长期驻扎在这里……。
将自己编写的程序以守护进程的形式启动。
将棋程序是恶魔吗?
你已经进入了主循环吗?
./apery
bench
按下右键或其他键之后,板凳就会移动,这是怎么回事呢?
当我输入“bench”,它会跑起来,但是当我输入“usi”,它却不动。有什么不同呢?
unknown command: usi
eval
-243
评估结果还可以吗?
print
unknown command: print
为什么不能打印?
key
4543979467506711947
钥匙可以吗?
tosfen
sfen l5knl/7b1/p3pg1gp/1pr3Pp1/5pS2/1PpGP4/2gpBPS1P/4K2R1/LN5NL w 2Sn5p 74
Tosfen 可以吗?
d
' 9 8 7 6 5 4 3 2 1
P1-KY * * * * * -OU-KE-KY
P2 * * * * * * * -KA *
P3-FU * * * -FU-KI * -KI-FU
P4 * -FU-HI * * * +FU-FU *
P5 * * * * * -FU+GI * *
P6 * +FU-FU+KI+FU * * * *
P7 * * -KI-FU+KA+FU+GI * +FU
P8 * * * * +OU * * +HI *
P9+KY+KE * * * * * +KE+KY
P+00GI00GI
P-00FU00FU00FU00FU00FU
P-00KE
-
key = 4543979467506711947
d可以吗?print不行。
s
' 9 8 7 6 5 4 3 2 1
P1-KY * * * * * -OU-KE-KY
P2 * * * * * * * -KA *
P3-FU * * * -FU-KI * -KI-FU
P4 * -FU-HI * * * +FU-FU *
P5 * * * * * -FU+GI * *
P6 * +FU-FU+KI+FU * * * *
P7 * * -KI-FU+KA+FU+GI * +FU
P8 * * * * +OU * * +HI *
P9+KY+KE * * * * * +KE+KY
P+00GI00GI
P-00FU00FU00FU00FU00FU
P-00KE
-
key = 4543979467506711947
elapsed = 2870 [msec]
times/s = 1742160 [times/sec]
num of moves = 78
6768TO, 2266KA, 7434HI, 2334KI, 4334KI, 1314FU, 2425FU, 4546FU, 5354FU, 8485FU, 9394FU, 1112KY, 9192KY, 2133KE, 2233KA, 2244KA, 2255KA, 7444HI, 7454HI, 7464HI, 7471HI, 7472HI, 7473HI, 7475HI, 2314KI, 2333KI, 4333KI, 4342KI, 4344KI, 4354KI, 7768KI, 7778KI, 7787KI, 7788KI, 3132OU, 3141OU, 3142OU, 0032FU, 0033FU, 0036FU, 0038FU, 0012KE, 0014KE, 0015KE, 0016KE, 0025KE, 0026KE, 0027KE, 0032KE, 0033KE, 0036KE, 0041KE, 0042KE, 0044KE, 0046KE, 0051KE, 0052KE, 0054KE, 0055KE, 0061KE, 0062KE, 0063KE, 0064KE, 0065KE, 0071KE, 0072KE, 0073KE, 0075KE, 0081KE, 0082KE, 0083KE, 0085KE, 0087KE, 0092KE, 0094KE, 0095KE, 0096KE, 0097KE,
s もいける。
t
None
可以的。 de.)
b
I cannot open
b也可以。
あーっ。
#if defined LEARN
打印 是用于学习的命令吗?
write_eval
哎呀,似乎要花些时间。按下[Ctrl]键加[C]键。
setoption
No such option:
可以设置选项,看起来不错。
isready
readyok
isready もいけてるじゃないか。
usi
id name ukamuse_SDT4
id author Hiraoka Takuya
option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Draw_Ply type spin default 256 min 1 max 2147483647
option name Engine_Name type string default ukamuse_SDT4
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
option name Move_Overhead type spin default 30 min 0 max 5000
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Slow_Mover type spin default 89 min 1 max 1000
option name Slow_Mover_10 type spin default 10 min 1 max 1000
option name Slow_Mover_16 type spin default 20 min 1 max 1000
option name Slow_Mover_20 type spin default 40 min 1 max 1000
option name Threads type spin default 2 min 1 max 256
option name Time_Margin type spin default 4500 min 0 max 2147483647
option name USI_Hash type spin default 256 min 1 max 1048576
option name USI_Ponder type check default true
usiok
usi もいけてるじゃないか。
那么,我们来尝试手动对局吧,看看有没有办法。我们重新开始一次。
咱们来手动对局吧
私が打つ
./apery
usi
次、浮かむ瀬が返してくる。
id name ukamuse_SDT4
id author Hiraoka Takuya
option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Draw_Ply type spin default 256 min 1 max 2147483647
option name Engine_Name type string default ukamuse_SDT4
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
option name Move_Overhead type spin default 30 min 0 max 5000
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Slow_Mover type spin default 89 min 1 max 1000
option name Slow_Mover_10 type spin default 10 min 1 max 1000
option name Slow_Mover_16 type spin default 20 min 1 max 1000
option name Slow_Mover_20 type spin default 40 min 1 max 1000
option name Threads type spin default 2 min 1 max 256
option name Time_Margin type spin default 4500 min 0 max 2147483647
option name USI_Hash type spin default 256 min 1 max 1048576
option name USI_Ponder type check default true
usiok
我来打一次。
usinewgame
position startpos moves
go
次、被冲刷的浪潮返回。
info string optimum_time = 20
info string maximum_time = 20
info string book_ply 32767
info depth 1 seldepth 1 multipv 1 score cp 0 nodes 67 nps 1367 time 49 pv 1g1f
bestmove 1g1f
在脑中调整着将棋盘。1g1f就是1六歩,但为什么要推侧行前角呢?
那就改为1四歩吧。
position sfen lnsgkgsnl/1b5r1/pppppppp1/8p/9/8P/PPPPPPPP1/1B5R1/LNSGKGSNL b - 1 moves 1g1f 1c1d
go
有些念头不请自来就立刻浮现。
info string optimum_time = 20
info string maximum_time = 20
info string book_ply 32767
info depth 1 seldepth 1 multipv 1 score cp 0 nodes 72 nps 3272 time 22 pv 2g2f
info depth 2 seldepth 2 multipv 1 score cp 0 nodes 195 nps 4062 time 48 pv 2g2f 2c2d
bestmove 2g2f ponder 2c2d
为什么会那么匆忙呢?总之,似乎可以指派给浮现的机会。
好吧,结束吧……。
由我来打。
gameover
quit
あとは設定をいじろう。
让我们来看一下设定
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
为了学习的目的,是否要让它在0.02秒内回答呢?
如果要让计算机在1秒内完成指令,为了考虑通信所需的时间,可能要留3秒左右,但由于无法满足需求的定义,可能要考虑让它思考约0.5秒左右。
setoption name Minimum_Thinking_Time value 500
在开始usinewgame之前,我是否应该把这个发送给思考引擎呢?
./apery
usi
id name ukamuse_SDT4
id author Hiraoka Takuya
option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Draw_Ply type spin default 256 min 1 max 2147483647
option name Engine_Name type string default ukamuse_SDT4
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
option name Move_Overhead type spin default 30 min 0 max 5000
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Slow_Mover type spin default 89 min 1 max 1000
option name Slow_Mover_10 type spin default 10 min 1 max 1000
option name Slow_Mover_16 type spin default 20 min 1 max 1000
option name Slow_Mover_20 type spin default 40 min 1 max 1000
option name Threads type spin default 2 min 1 max 256
option name Time_Margin type spin default 4500 min 0 max 2147483647
option name USI_Hash type spin default 256 min 1 max 1048576
option name USI_Ponder type check default true
usiok
isready
readyok
setoption name Minimum_Thinking_Time value 500
usinewgame
position startpos moves
go
info string optimum_time = 500
info string maximum_time = 500
info string book_ply 32767
info depth 1 seldepth 1 multipv 1 score cp 63 nodes 64 nps 1230 time 52 pv 2g2f
info depth 2 seldepth 2 multipv 1 score cp 173 nodes 108 nps 1611 time 67 pv 2g2f 1c1d
info depth 3 seldepth 3 multipv 1 score cp 155 nodes 229 nps 2462 time 93 pv 2g2f 3c3d 2f2e
info depth 4 seldepth 4 multipv 1 score cp 291 nodes 341 nps 2772 time 123 pv 2g2f 3c3d 2f2e 1c1d 2e2d
info depth 5 seldepth 5 multipv 1 score cp 252 nodes 1781 nps 6720 time 265 pv 2g2f 8c8d 2f2e 8d8e 2e2d 2c2d 2h2d
info depth 6 seldepth 6 multipv 1 score cp 252 nodes 2047 nps 6603 time 310 pv 2g2f 8c8d 2f2e 8d8e 2e2d 2c2d 2h2d
info depth 7 seldepth 7 multipv 1 score cp 252 nodes 2653 nps 6615 time 401 pv 2g2f 8c8d 2f2e 8d8e 2e2d 2c2d 2h2d 8e8f
info depth 8 seldepth 9 multipv 1 score cp 22 nodes 6478 nps 6733 time 962 pv 2g2f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f
bestmove 2g2f ponder 8c8d
嗯,看起来他思考了超过0.5秒,正在延伸飞车前方的步子,所以应该没问题。单凭这一点来看……。
下一个是Shell脚本吗?
希望能将正在等待循环的漂浮关口转变为标准输入为shell脚本或其他形式,标准输出也是shell脚本或其他形式,如果能实现捕捉并进行操作就好了。既然能在将棋程序中实现,那肯定有方法可以做到吧……。
也许甚至可以使用C++,但如果可能的话,我更希望与PHP进行协作。
我们下次再考虑有哪些方法可供选择。
既然已经能够通过键入与标准输入输出通信,那么应该也可以在Shell中实现。让我们进行调查。
用哪个壳?
当我用谷歌搜索时,只能看到bash。那就用bash吧。
有人说编辑器 Ubuntu 上默认安装了 gedit,但在我的电脑上并未安装,所以我会用我电脑环境中默认安装的nano。
「シェルスクリプト入門 ウェブ上のまとめ」(「Memo on the Web」)
http://motw.mods.jp/shellscript/tutorial.html
【Chinese】
「Shell脚本入门 网页上的概述」(“Web上的备忘录”)
http://motw.mods.jp/shellscript/tutorial.html
mkdir jikken
cd jikken
nano tamesi1
#!/bin/sh
echo "hello, world"
按下[Ctrl]+[O]
在 Tamesi1 上取一个名字并保存。
哦,这个文本变得有颜色了。
按下[Ctrl]和[X]键。
关闭nano编辑器。
./tamesi1
-bash: ./tamesi1: Permission denied
有权限吗?
ls -an
total 12
drwxrwxr-x 2 1000 1000 4096 Mar 5 16:30 .
drwxr-xr-x 6 1000 1000 4096 Mar 5 16:28 ..
-rw-rw-r-- 1 1000 1000 30 Mar 5 16:30 tamesi1
那么
chmod 765 tamesi1
这样可以吗?不可能的。需要管理员权限吗?
sudo su -
~パスワード入力~
chmod 765 tamesi1
ls -an
total 12
drwxrwxr-x 2 1000 1000 4096 Mar 5 16:30 .
drwxr-xr-x 6 1000 1000 4096 Mar 5 16:28 ..
-rwxrw-r-x 1 1000 1000 30 Mar 5 16:30 tamesi1
~ ~
※ここが変わった
./tamesi1
hello, world
哦,可以了。
那就在 bin 文件夹里写一个脚本吧。
cd ../shogi/apery-SDT4/bin
啊!这不是这边。
cd ../../ukamuse_sdt4/bin
我有一些.exe文件,但在Ubuntu上不会使用吧……我应该删除它们吗?
rm ukamuse_sdt4_bmi2.exe
rm ukamuse_sdt4_sse2.exe
rm ukamuse_sdt4_sse41.exe
rm ukamuse_sdt4_sse42.exe
在文本编辑器中写下并复制,然后在PuTTY中用左键点击粘贴,按下[Enter]键一次即可完成全部操作。
让我们编写一个Shell脚本吧。
那么,用这种方式写是否可以呢?
首先,在台子上试一试。
nano tamesi1
#!/bin/sh
./apery
bench
右键点击粘贴到 PuTTY 中,保存并退出 nano。
./tamesi1
-su: ./tamesi1: Permission denied
ls -an
total 852
drwxr-xr-x 3 0 0 4096 Mar 5 16:44 .
drwxr-xr-x 6 0 0 4096 Mar 5 02:33 ..
drwxr-xr-x 2 0 0 4096 Oct 7 11:05 20161007
-rwxr-xr-x 1 0 0 848120 Mar 5 02:47 apery
-rw-r--r-- 1 0 0 1531 Mar 5 03:04 benchmark.sfen
-rw-r--r-- 1 0 0 24 Mar 5 16:44 tamesi1
chmod 744 tamesi1
ls -n
total 844
drwxr-xr-x 2 0 0 4096 Oct 7 11:05 20161007
-rwxr-xr-x 1 0 0 848120 Mar 5 02:47 apery
-rw-r--r-- 1 0 0 1531 Mar 5 03:04 benchmark.sfen
-rwxr--r-- 1 0 0 24 Mar 5 16:44 tamesi1
~
※ここが変わった
./tamesi1
他好像进入了待机循环,但是是不是输入”bench”太快了?
bench
键入并进行操作。是否需要等待几秒钟,然后再输入 bench 比较好呢?
使用[Ctrl]+[C]进行中止。
等待几秒钟后再进行输入
「【休眠】在指定的时间停止运行」(ITPro)
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230884/?rt=nocnt
那么,让我们从启动漂浮台开始,等待十秒钟,然后输入”bench”。
#!/bin/sh
./apery
sleep 10s
bench
使用 nano 进行编辑,通过命令行执行。
被封锁了。那么,是写法不同吗?像这样。
#!/bin/sh
./apery
sleep 10s
echo 'bench'
这还是被阻止着……。难道是在/apery的行里阻止吗?如果是的话,这样怎么样?
#!/bin/sh
./apery &
sleep 3s
echo 'bench' | ./apery
中文翻译:太棒了!成功了。
那么,是否需要睡眠之类的东西呢?
#!/bin/sh
./apery &
echo 'bench' | ./apery
这样也可以。那么,bench就是这个。
让我们尝试使用Shell脚本来编写棋局。
我会在外出后添加说明。
使用PuTTY工具,输入IP地址,通过SSH协议进行登录。输入用户名和密码。
sudo su -
再次输入密码。
cd ../home/ユーザー名/shogi/ukamuse_sdt4/bin
ls
好的。
让我们来创建一个名为tamesi2的文件吧。
nano tamesi2
#!/bin/sh
./apery &
echo 'usi' | ./apery
ls -n
~略~
-rw-r--r-- 1 0 0 41 Mar 5 18:25 tamesi2
chmod 744 tamesi2
ls -n
~略~
-rwxr--r-- 1 0 0 41 Mar 5 18:25 tamesi2
./tamesi2
id name ukamuse_SDT4
~略~
usiok
用Shell的变量接收命令的输出
要在Shell脚本中接收这个可变部分的输出该怎么办呢?通过文本文件传递可能行得通,但是……?
「函数的使用方法」(UNIX和Linux命令/Shell脚本参考)
http://shellscript.sunone.me/function.html
这是一个函数的例子吗?是无法通过重定向传递变量的吗?
将命令执行结果设置为变量 (UNIX & Linux 命令/Shell 脚本参考)
http://shellscript.sunone.me/variable.html#将命令执行结果设置为变量
VAR=`command`
echo $VAR
哇,真的吗?
VAR=$(command)
echo $VAR
嗯。看来,( )的方可嵌套。
var=$(expr $(expr $(date '+%Y') + $(date '+%m')) + $(date '+%d'))
echo $VAR
我不明白这是什么,但可能会有使用的情况。
那么,就这样吧。
nano tamesi3
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
echo '(^o^)$VAR'
chmod 744 tamesi3
./tamesi3
(^o^)$VAR
嗯。
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
echo '(^o^)${VAR}'
./tamesi3
(^o^)${VAR}
唔。
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
echo '(^o^)$(VAR)'
./tamesi3
(^o^)$(VAR)
嗯。
「【连接多个变量】」(ITPro)
链接:http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231154/
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
echo "(^o^)${VAR}"
./tamesi3
(^o^)id name ukamuse_SDT4
~略~
usiok
哦!
用bash将多行文本分割为每行一个,并为每一行编写相应的处理代码。
就算是C#语言也很简单的啊……可是在bash脚本中要怎么做呢?
「按行处理」(Qiita)
http://qiita.com/kazu56/items/83340a2e284298b9e237
猫命令是什么?
「【Linux指令集】3分钟学会使用cat指令」(工程师入门)
嗯。你是说要将通过参数指定的文件内容逐行输出到标准输出吗?那好,我试试看。
哎呀!我本来特地用变量接收的,可是通过文件传输就没有意义了呀。
那么,这样可以吗?
若需要具有本地中文风格的同义句,只需一种选项:
“若需求以中文为母语的表述方式,只需一种选项:”
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
# 区切り文字は NewLine で。
IFS=$'\n'
for line in $VAR
do
echo "(^o^)$line"
done
哎呀,PuTTY上的日文字体显示有问题啊。虽然能读懂但还是有点奇怪……。
chmod 744 tamesi4
./tamesi4
(^o^)id
(^o^)ame ukamuse_SDT4
id author Hiraoka Takuya
optio
(^o^)
(^o^)ame Best_Book_Move type check default false
optio
(^o^)
(^o^)ame Book_File type stri
(^o^)g default book/20150503/book.bi
(^o^)
optio
(^o^)
(^o^)ame Byoyomi_Margi
(^o^) type spi
(^o^) default 500 mi
(^o^) 0 max 2147483647
optio
(^o^)
(^o^)ame Clear_Hash type butto
(^o^)
optio
(^o^)
(^o^)ame Draw_Ply type spi
(^o^) default 256 mi
(^o^) 1 max 2147483647
optio
(^o^)
(^o^)ame E
(^o^)gi
(^o^)e_Name type stri
(^o^)g default ukamuse_SDT4
optio
(^o^)
(^o^)ame Max_Book_Ply type spi
(^o^) default 32767 mi
(^o^) 0 max 32767
optio
(^o^)
(^o^)ame Max_Ra
(^o^)dom_Score_Diff type spi
(^o^) default 0 mi
(^o^) 0 max 32600
optio
(^o^)
(^o^)ame Max_Ra
(^o^)dom_Score_Diff_Ply type spi
(^o^) default 32767 mi
(^o^) 0 max 32767
optio
(^o^)
(^o^)ame Mi
(^o^)_Book_Ply type spi
(^o^) default 32767 mi
(^o^) 0 max 32767
optio
(^o^)
(^o^)ame Mi
(^o^)_Book_Score type spi
(^o^) default -180 mi
(^o^) -32601 max 32601
optio
(^o^)
(^o^)ame Mi
(^o^)imum_Thi
(^o^)ki
(^o^)g_Time type spi
(^o^) default 20 mi
(^o^) 0 max 2147483647
optio
(^o^)
(^o^)ame Move_Overhead type spi
(^o^) default 30 mi
(^o^) 0 max 5000
optio
(^o^)
(^o^)ame MultiPV type spi
(^o^) default 1 mi
(^o^) 1 max 594
optio
(^o^)
(^o^)ame Ow
(^o^)Book type check default true
optio
(^o^)
(^o^)ame Slow_Mover type spi
(^o^) default 89 mi
(^o^) 1 max 1000
optio
(^o^)
(^o^)ame Slow_Mover_10 type spi
(^o^) default 10 mi
(^o^) 1 max 1000
optio
(^o^)
(^o^)ame Slow_Mover_16 type spi
(^o^) default 20 mi
(^o^) 1 max 1000
optio
(^o^)
(^o^)ame Slow_Mover_20 type spi
(^o^) default 40 mi
(^o^) 1 max 1000
optio
(^o^)
(^o^)ame Threads type spi
(^o^) default 2 mi
(^o^) 1 max 256
optio
(^o^)
(^o^)ame Time_Margi
(^o^) type spi
(^o^) default 4500 mi
(^o^) 0 max 2147483647
optio
(^o^)
(^o^)ame USI_Hash type spi
(^o^) default 256 mi
(^o^) 1 max 1048576
optio
(^o^)
(^o^)ame USI_Po
(^o^)der type check default true
usiok
这是什么东西。
在文字中是否有换行……?
试着在分隔符号行首加上 #,暂时注释掉。
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
# 区切り文字は NewLine で。
# IFS=$'\n'
for line in $VAR
do
echo "(^o^)$line"
done
./tamesi4
(^o^)id
(^o^)name
(^o^)ukamuse_SDT4
(^o^)id
(^o^)author
(^o^)Hiraoka
(^o^)Takuya
(^o^)option
(^o^)name
(^o^)Best_Book_Move
(^o^)type
(^o^)check
(^o^)default
(^o^)false
(^o^)option
(^o^)name
~以下略~
所有的白色空格都是分隔符吗?
我们试试用双引号来包含换行符 “\n”。
IFS=$"\n"
不行。
IFS=$"\n"
不行。
IFS=$'\t\n'
不行。字母 t 已经消失了。
IFS=$'\\n'
不行。
IFS=$"\\n"
不行。
IFS="\\n"
不行。
要将bash的IFS设置为仅包含换行符,请参考以下链接「计算机和娱乐的日子」(http://d.hatena.ne.jp/n9d/20090313/1236912316)。
IFS='
'
可以了。
./tamesi4
(^o^)id name ukamuse_SDT4
(^o^)id author Hiraoka Takuya
(^o^)option name Best_Book_Move type check default false
(^o^)option name Book_File type string default book/20150503/book.bin
(^o^)option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
~以下略~
好的,那就暫時將每一行分開來。
接下來,我們想要用半角空格將分開的每一行再進行分隔。
由于嵌套循环可能会增加重置分隔符的工作量,所以希望将行分割的结果放入数组,并分为另一个循环进行处理。
怎么使用数组?
「bash 数组总结」 (Qiita)
http://qiita.com/b4b4r07/items/e56a8e3471fb45df2f59
这是什么鬼东西,好复杂啊。
我不知道如何创建可变长数组。
能够一边分割一边在数组中进行获取吗?
「使用Bash将字符串转换为数组,并在for循环中遍历它」(我想成为水母。)
请以中文对以下内容进行本土化改写,仅需提供一种改写选项:
“Can you recommend a good restaurant in this area?”
将其转换为数组。
将$text的值赋给数组array_text=(echo $text)。
让我们来试试看。
nano tamesi5
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
# 改行で分割して配列に入れる
LINES=(`echo $VAR`)
for line in $LINES
do
echo "(^o^)$line"
done
哎呀?我之前把单引号和反引号弄错了吗?
chmod 744 tamesi5
./tamesi5
./tamesi5: 6: ./tamesi5: Syntax error: "(" unexpected
这难道不是错了吗?
LINES=$("echo $VAR")
哇,输出有些问题。像这样。
LINES=$(echo $VAR)
./tamesi5
(^o^)id
(^o^)name
(^o^)ukamuse_SDT4
(^o^)id
(^o^)author
只有在 echo 命令中设置分隔符吗……?
哎呀,好像tamesi5已经被抓住了。
kill %1
虽然尝试停下来了。嗯。
ls -an
~中略~
-rwxr--r-- 1 0 0 156 Mar 5 20:01 tamesi5
-rw-r--r-- 1 0 0 1024 Mar 5 20:01 .tamesi5.swp
还有没有锁定的文件?可以删除吗?
rm .tamesi5.swp
请tamesi5编辑,看看这个版本怎么样。
# 区切り文字IFSは改行だけで分割して配列に入れる
IFS='
'
LINES=$(echo $VAR)
那个输出结果好像连接在一行上了。
那么,我们试试使用数组添加元素的方式。
#!/bin/sh
./apery &
VAR=$(echo 'usi' | ./apery)
# 行分割して配列に入れる
LINES=()
# 区切り文字は 改行だけで。
IFS='
'
for line in $VAR
do
LINES=("${LINES[@]}" $line)
done
for line in $LINES
do
echo "(^o^)$line"
done
./tamesi5
./tamesi5: 6: ./tamesi5: Syntax error: "(" unexpected
嗯。
“用bash或sh处理数组。” (人生太短暂了,没有时间去讨厌自己的工作。)
改寫成自然中文的句子:
由於sh沒有陣列,所以似乎最好使用bash。那麼文件的開頭應該使用哪個呢?
#!/bin/sh
这样说
#!/bin/bash
进行更改。
./tamesi5
(^o^)id name ukamuse_SDT4
我收到了一行。让我们检查一下数组的元素数量。
echo ${#array[@]}
./tamesi5
0
(^o^)id name ukamuse_SDT4
嗯。
這樣啊。
echo ${#LINES[@]}
./tamesi5
26
(^o^)id name ukamuse_SDT4
我能够将数组分割吗?
「查看数组数据」(Qiita)
http://qiita.com/b4b4r07/items/e56a8e3471fb45df2f59
那么,就这样吧。
i=0
for line in ${LINES[@]}
do
echo "(^q^)[$i] = $line"
let i++
done
./tamesi5
26
(^q^)[0] = id name ukamuse_SDT4
(^q^)[1] = id author Hiraoka Takuya
(^q^)[2] = option name Best_Book_Move type check default false
(^q^)[3] = option name Book_File type string default book/20150503/book.bin
(^q^)[4] = option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
(^q^)[5] = option name Clear_Hash type button
(^q^)[6] = option name Draw_Ply type spin default 256 min 1 max 2147483647
(^q^)[7] = option name Engine_Name type string default ukamuse_SDT4
(^q^)[8] = option name Max_Book_Ply type spin default 32767 min 0 max 32767
(^q^)[9] = option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
(^q^)[10] = option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
(^q^)[11] = option name Min_Book_Ply type spin default 32767 min 0 max 32767
(^q^)[12] = option name Min_Book_Score type spin default -180 min -32601 max 32601
(^q^)[13] = option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
(^q^)[14] = option name Move_Overhead type spin default 30 min 0 max 5000
(^q^)[15] = option name MultiPV type spin default 1 min 1 max 594
(^q^)[16] = option name OwnBook type check default true
(^q^)[17] = option name Slow_Mover type spin default 89 min 1 max 1000
(^q^)[18] = option name Slow_Mover_10 type spin default 10 min 1 max 1000
(^q^)[19] = option name Slow_Mover_16 type spin default 20 min 1 max 1000
(^q^)[20] = option name Slow_Mover_20 type spin default 40 min 1 max 1000
(^q^)[21] = option name Threads type spin default 2 min 1 max 256
(^q^)[22] = option name Time_Margin type spin default 4500 min 0 max 2147483647
(^q^)[23] = option name USI_Hash type spin default 256 min 1 max 1048576
(^q^)[24] = option name USI_Ponder type check default true
(^q^)[25] = usiok
好的!
将数组的元素内容转换为以空格分隔
这个合适吗?
nano tamesi6
#!/bin/bash
./apery &
VAR=$(echo 'usi' | ./apery)
# 行分割して配列に入れる
LINES=()
# 区切り文字は 改行だけで
IFS='
'
for line in $VAR
do
LINES=("${LINES[@]}" $line)
done
# echo ${#LINES[@]}
iLine=0
for line in ${LINES[@]}
do
echo "(^q^)[$iLine] = $line"
# 行分割して配列に入れる
TOKENS=()
# 区切り文字は 半角スペースだけで
IFS=' '
iToken=0
for token in $line
do
TOKENS=("${TOKENS[@]}" $token)
echo "(^q^)[$iLine][$iToken] = $token"
let iToken++
done
let iLine++
done
chmod 744 tamesi6
./tamesi6
(^q^)[0] = id name ukamuse_SDT4
(^q^)[0][0] = id
(^q^)[0][1] = name
(^q^)[0][2] = ukamuse_SDT4
(^q^)[1] = id author Hiraoka Takuya
(^q^)[1][0] = id
(^q^)[1][1] = author
(^q^)[1][2] = Hiraoka
(^q^)[1][3] = Takuya
(^q^)[2] = option name Best_Book_Move type check default false
(^q^)[2][0] = option
(^q^)[2][1] = name
(^q^)[2][2] = Best_Book_Move
(^q^)[2][3] = type
(^q^)[2][4] = check
(^q^)[2][5] = default
(^q^)[2][6] = false
(^q^)[3] = option name Book_File type string default book/20150503/book.bin
(^q^)[3][0] = option
(^q^)[3][1] = name
(^q^)[3][2] = Book_File
(^q^)[3][3] = type
(^q^)[3][4] = string
(^q^)[3][5] = default
(^q^)[3][6] = book/20150503/book.bin
(^q^)[4] = option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
(^q^)[4][0] = option
(^q^)[4][1] = name
(^q^)[4][2] = Byoyomi_Margin
(^q^)[4][3] = type
(^q^)[4][4] = spin
(^q^)[4][5] = default
(^q^)[4][6] = 500
(^q^)[4][7] = min
(^q^)[4][8] = 0
(^q^)[4][9] = max
(^q^)[4][10] = 2147483647
(^q^)[5] = option name Clear_Hash type button
(^q^)[5][0] = option
(^q^)[5][1] = name
(^q^)[5][2] = Clear_Hash
(^q^)[5][3] = type
(^q^)[5][4] = button
(^q^)[6] = option name Draw_Ply type spin default 256 min 1 max 2147483647
(^q^)[6][0] = option
(^q^)[6][1] = name
(^q^)[6][2] = Draw_Ply
(^q^)[6][3] = type
(^q^)[6][4] = spin
(^q^)[6][5] = default
(^q^)[6][6] = 256
(^q^)[6][7] = min
(^q^)[6][8] = 1
(^q^)[6][9] = max
(^q^)[6][10] = 2147483647
(^q^)[7] = option name Engine_Name type string default ukamuse_SDT4
(^q^)[7][0] = option
(^q^)[7][1] = name
(^q^)[7][2] = Engine_Name
(^q^)[7][3] = type
(^q^)[7][4] = string
(^q^)[7][5] = default
(^q^)[7][6] = ukamuse_SDT4
(^q^)[8] = option name Max_Book_Ply type spin default 32767 min 0 max 32767
(^q^)[8][0] = option
(^q^)[8][1] = name
(^q^)[8][2] = Max_Book_Ply
(^q^)[8][3] = type
(^q^)[8][4] = spin
(^q^)[8][5] = default
(^q^)[8][6] = 32767
(^q^)[8][7] = min
(^q^)[8][8] = 0
(^q^)[8][9] = max
(^q^)[8][10] = 32767
(^q^)[9] = option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
(^q^)[9][0] = option
(^q^)[9][1] = name
(^q^)[9][2] = Max_Random_Score_Diff
(^q^)[9][3] = type
(^q^)[9][4] = spin
(^q^)[9][5] = default
(^q^)[9][6] = 0
(^q^)[9][7] = min
(^q^)[9][8] = 0
(^q^)[9][9] = max
(^q^)[9][10] = 32600
(^q^)[10] = option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
(^q^)[10][0] = option
(^q^)[10][1] = name
(^q^)[10][2] = Max_Random_Score_Diff_Ply
(^q^)[10][3] = type
(^q^)[10][4] = spin
(^q^)[10][5] = default
(^q^)[10][6] = 32767
(^q^)[10][7] = min
(^q^)[10][8] = 0
(^q^)[10][9] = max
(^q^)[10][10] = 32767
(^q^)[11] = option name Min_Book_Ply type spin default 32767 min 0 max 32767
(^q^)[11][0] = option
(^q^)[11][1] = name
(^q^)[11][2] = Min_Book_Ply
(^q^)[11][3] = type
(^q^)[11][4] = spin
(^q^)[11][5] = default
(^q^)[11][6] = 32767
(^q^)[11][7] = min
(^q^)[11][8] = 0
(^q^)[11][9] = max
(^q^)[11][10] = 32767
(^q^)[12] = option name Min_Book_Score type spin default -180 min -32601 max 32601
(^q^)[12][0] = option
(^q^)[12][1] = name
(^q^)[12][2] = Min_Book_Score
(^q^)[12][3] = type
(^q^)[12][4] = spin
(^q^)[12][5] = default
(^q^)[12][6] = -180
(^q^)[12][7] = min
(^q^)[12][8] = -32601
(^q^)[12][9] = max
(^q^)[12][10] = 32601
(^q^)[13] = option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
(^q^)[13][0] = option
(^q^)[13][1] = name
(^q^)[13][2] = Minimum_Thinking_Time
(^q^)[13][3] = type
(^q^)[13][4] = spin
(^q^)[13][5] = default
(^q^)[13][6] = 20
(^q^)[13][7] = min
(^q^)[13][8] = 0
(^q^)[13][9] = max
(^q^)[13][10] = 2147483647
(^q^)[14] = option name Move_Overhead type spin default 30 min 0 max 5000
(^q^)[14][0] = option
(^q^)[14][1] = name
(^q^)[14][2] = Move_Overhead
(^q^)[14][3] = type
(^q^)[14][4] = spin
(^q^)[14][5] = default
(^q^)[14][6] = 30
(^q^)[14][7] = min
(^q^)[14][8] = 0
(^q^)[14][9] = max
(^q^)[14][10] = 5000
(^q^)[15] = option name MultiPV type spin default 1 min 1 max 594
(^q^)[15][0] = option
(^q^)[15][1] = name
(^q^)[15][2] = MultiPV
(^q^)[15][3] = type
(^q^)[15][4] = spin
(^q^)[15][5] = default
(^q^)[15][6] = 1
(^q^)[15][7] = min
(^q^)[15][8] = 1
(^q^)[15][9] = max
(^q^)[15][10] = 594
(^q^)[16] = option name OwnBook type check default true
(^q^)[16][0] = option
(^q^)[16][1] = name
(^q^)[16][2] = OwnBook
(^q^)[16][3] = type
(^q^)[16][4] = check
(^q^)[16][5] = default
(^q^)[16][6] = true
(^q^)[17] = option name Slow_Mover type spin default 89 min 1 max 1000
(^q^)[17][0] = option
(^q^)[17][1] = name
(^q^)[17][2] = Slow_Mover
(^q^)[17][3] = type
(^q^)[17][4] = spin
(^q^)[17][5] = default
(^q^)[17][6] = 89
(^q^)[17][7] = min
(^q^)[17][8] = 1
(^q^)[17][9] = max
(^q^)[17][10] = 1000
(^q^)[18] = option name Slow_Mover_10 type spin default 10 min 1 max 1000
(^q^)[18][0] = option
(^q^)[18][1] = name
(^q^)[18][2] = Slow_Mover_10
(^q^)[18][3] = type
(^q^)[18][4] = spin
(^q^)[18][5] = default
(^q^)[18][6] = 10
(^q^)[18][7] = min
(^q^)[18][8] = 1
(^q^)[18][9] = max
(^q^)[18][10] = 1000
(^q^)[19] = option name Slow_Mover_16 type spin default 20 min 1 max 1000
(^q^)[19][0] = option
(^q^)[19][1] = name
(^q^)[19][2] = Slow_Mover_16
(^q^)[19][3] = type
(^q^)[19][4] = spin
(^q^)[19][5] = default
(^q^)[19][6] = 20
(^q^)[19][7] = min
(^q^)[19][8] = 1
(^q^)[19][9] = max
(^q^)[19][10] = 1000
(^q^)[20] = option name Slow_Mover_20 type spin default 40 min 1 max 1000
(^q^)[20][0] = option
(^q^)[20][1] = name
(^q^)[20][2] = Slow_Mover_20
(^q^)[20][3] = type
(^q^)[20][4] = spin
(^q^)[20][5] = default
(^q^)[20][6] = 40
(^q^)[20][7] = min
(^q^)[20][8] = 1
(^q^)[20][9] = max
(^q^)[20][10] = 1000
(^q^)[21] = option name Threads type spin default 2 min 1 max 256
(^q^)[21][0] = option
(^q^)[21][1] = name
(^q^)[21][2] = Threads
(^q^)[21][3] = type
(^q^)[21][4] = spin
(^q^)[21][5] = default
(^q^)[21][6] = 2
(^q^)[21][7] = min
(^q^)[21][8] = 1
(^q^)[21][9] = max
(^q^)[21][10] = 256
(^q^)[22] = option name Time_Margin type spin default 4500 min 0 max 2147483647
(^q^)[22][0] = option
(^q^)[22][1] = name
(^q^)[22][2] = Time_Margin
(^q^)[22][3] = type
(^q^)[22][4] = spin
(^q^)[22][5] = default
(^q^)[22][6] = 4500
(^q^)[22][7] = min
(^q^)[22][8] = 0
(^q^)[22][9] = max
(^q^)[22][10] = 2147483647
(^q^)[23] = option name USI_Hash type spin default 256 min 1 max 1048576
(^q^)[23][0] = option
(^q^)[23][1] = name
(^q^)[23][2] = USI_Hash
(^q^)[23][3] = type
(^q^)[23][4] = spin
(^q^)[23][5] = default
(^q^)[23][6] = 256
(^q^)[23][7] = min
(^q^)[23][8] = 1
(^q^)[23][9] = max
(^q^)[23][10] = 1048576
(^q^)[24] = option name USI_Ponder type check default true
(^q^)[24][0] = option
(^q^)[24][1] = name
(^q^)[24][2] = USI_Ponder
(^q^)[24][3] = type
(^q^)[24][4] = check
(^q^)[24][5] = default
(^q^)[24][6] = true
(^q^)[25] = usiok
(^q^)[25][0] = usiok
你行不行。
我们把它变成一个子程序吧。
将将一行文本分割并存入数组的部分,提取出来作为一个子程序。
nano tamesi7
#!/bin/bash
# 一行をトークン区切り配列へ
# $1...line
Line_To_Tokens(){
TOKENS=()
# 区切り文字は 半角スペースだけで
IFS=' '
iToken=0
for token in $1
do
TOKENS=("${TOKENS[@]}" $token)
let iToken++
done
# せっかく配列にいれても標準出力へ返すのか……
echo ${TOKENS[@]}
}
./apery &
VAR=$(echo 'usi' | ./apery)
# 行分割して配列に入れる
LINES=()
# 区切り文字は 改行だけで
IFS='
'
for line in $VAR
do
LINES=("${LINES[@]}" $line)
done
iLine=0
for line in ${LINES[@]}
do
# 行分割して配列に入れる
TOKENS=(`Line_To_Tokens $line`)
echo "(^q^)[$iLine] = ${TOKENS[@]}"
let iLine++
done
chmod 744 tamesi7
./tamesi7
(^q^)[0] = id name ukamuse_SDT4
(^q^)[1] = id author Hiraoka Takuya
(^q^)[2] = option name Best_Book_Move type check default false
(^q^)[3] = option name Book_File type string default book/20150503/book.bin
(^q^)[4] = option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
(^q^)[5] = option name Clear_Hash type button
(^q^)[6] = option name Draw_Ply type spin default 256 min 1 max 2147483647
(^q^)[7] = option name Engine_Name type string default ukamuse_SDT4
(^q^)[8] = option name Max_Book_Ply type spin default 32767 min 0 max 32767
(^q^)[9] = option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
(^q^)[10] = option name Max_Random_Score_Diff_Ply type spin default 32767 min 0 max 32767
(^q^)[11] = option name Min_Book_Ply type spin default 32767 min 0 max 32767
(^q^)[12] = option name Min_Book_Score type spin default -180 min -32601 max 32601
(^q^)[13] = option name Minimum_Thinking_Time type spin default 20 min 0 max 2147483647
(^q^)[14] = option name Move_Overhead type spin default 30 min 0 max 5000
(^q^)[15] = option name MultiPV type spin default 1 min 1 max 594
(^q^)[16] = option name OwnBook type check default true
(^q^)[17] = option name Slow_Mover type spin default 89 min 1 max 1000
(^q^)[18] = option name Slow_Mover_10 type spin default 10 min 1 max 1000
(^q^)[19] = option name Slow_Mover_16 type spin default 20 min 1 max 1000
(^q^)[20] = option name Slow_Mover_20 type spin default 40 min 1 max 1000
(^q^)[21] = option name Threads type spin default 2 min 1 max 256
(^q^)[22] = option name Time_Margin type spin default 4500 min 0 max 2147483647
(^q^)[23] = option name USI_Hash type spin default 256 min 1 max 1048576
(^q^)[24] = option name USI_Ponder type check default true
(^q^)[25] = usiok
好吧,按照预期的方式运行了。虽然没有像子程序化一样令人高兴……。
分类一下
在这里,当看到每一行的第一个单词(第一个标记)时,
– 身份
– 选择
– 可行
让我们先忽略id和option,写一个检查是否存在usiok的程序,从中我们可以确定其属于哪一个。
假设有 usiok 的情况下,将发送 “isready” 字符串到浮沙。
要获取文本的第一行。
如何使用cat命令读取第一行?(来自stackoverflow)http://stackoverflow.com/questions/6114119/how-do-i-read-first-line-using-cat
head -n 1 file.txt
如果要确认head命令的操作是否正确,应该怎么做呢?
FIRST_TOKEN=(`head -n 1 ${TOKENS[@]}`)
(^q^)[1] =
head: cannot open 'option name Best_Book_Move type check default false' for reading: No such file or directory
难道不是必须要文件吗?
「文字列抽出工具「cut」」(ITPro)
http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231159/
FIRST_TOKEN=(`echo ${TOKENS[@]} | cut -d "
"`)
(^q^)[0] =
cut: you must specify a list of bytes, characters, or fields
Try 'cut --help' for more information.
唔。
Shell命令大部分都是通过标准输入输出进行的吧。
那么,是不是直接通过文件传输比较好呢?
让我重新写一下。
我可以输出多行回声吗?
nano tamesi8
#!/bin/bash
# 引数1をスペース区切りにし、最初のトークンを出力
# $1...line
Line_To_FirstToken(){
TOKENS=()
# 区切り文字は 半角スペースだけで
IFS=' '
for token in $1
do
echo $token
return 0
done
}
./apery &
VAR=$(echo 'usi' | ./apery)
# 行分割して配列に入れる
LINES=()
# 区切り文字は 改行だけで
IFS='
'
for line in $VAR
do
LINES=("${LINES[@]}" $line)
done
iLine=0
for line in ${LINES[@]}
do
# 行分割して配列に入れる
FIRST_TOKEN=(`Line_To_FirstToken $line`)
echo "(^q^)[$iLine] = $FIRST_TOKEN"
let iLine++
done
chmod 744 tamesi8
./tamesi8
./tamesi8
(^q^)[0] = id
(^q^)[1] = id
(^q^)[2] = option
(^q^)[3] = option
(^q^)[4] = option
(^q^)[5] = option
(^q^)[6] = option
(^q^)[7] = option
(^q^)[8] = option
(^q^)[9] = option
(^q^)[10] = option
(^q^)[11] = option
(^q^)[12] = option
(^q^)[13] = option
(^q^)[14] = option
(^q^)[15] = option
(^q^)[16] = option
(^q^)[17] = option
(^q^)[18] = option
(^q^)[19] = option
(^q^)[20] = option
(^q^)[21] = option
(^q^)[22] = option
(^q^)[23] = option
(^q^)[24] = option
(^q^)[25] = usiok
总之,虽然我们能得到第一个标记,但感觉还不够清晰。
用C#编写将棋相关的程序,而不是使用bash脚本,然后通过与浮かむ瀬作为独立进程进行通信来实现。
那么,是不是应该安装 mono 呢?
让我们在 Ubuntu 上安装 Mono。
在Linux中,C#不受欢迎吗?
在Linux上编译Mono
如果我执行这个命令,会有什么结果呢?
sudo apt-get install git autoconf libtool automake build-essential mono-devel gettext cmake
有什么在动。
After this operation, 132 MB of additional disk space will be used.
Do you want to continue? [Y/n]
那么,我们继续前进吧。 , ba.)
done.
已经完成了安装。
那么让我们试着用C#语言写一个Hello World。
nano ShogiServer.cs
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hello, world");
}
}
}
Nano 不会为 C# 代码着色吗?
怎么编译呢?
其实,命令行要用到什么时候啊?是不是应该安装 GUI 呢?
man mono
不行,行数太多了。
mono --version
Mono JIT compiler version 4.2.1 (Debian 4.2.1.102+dfsg2-7ubuntu4)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: altstack
Notifications: epoll
Architecture: amd64
Disabled: none
Misc: softdebug
LLVM: supported, not enabled.
GC: sgen
哇,终于更新到第四版了。真是太好了,真是帮了大忙。
「使用csc.exe命令行进行构建」
C# 的编译器是 csc 吗?
csc ShogiServer.cs
The program 'csc' is currently not installed. You can install it by typing:
apt install chicken-bin
我没有进去……。
作為Xamarin的基礎,它包括了「Mono」和C#編譯器「mcs」(buildinsider)
C# 的编译器是 mcs 吗?
mcs ShogiServer.cs
ls
~略~
ShogiServer.cs
ShogiServer.exe
这个 .exe 可以运行在 Linux 上吗?
./ShogiServer.exe
hello, world
喔! (Oh!)
我能写C#的Makefile吗……。
让我们编写一个示例程序吧
那么,暂时我尝试编写一个示例程序,通过标准输入接收”usi”,然后返回”usiok”。
我不会说中文。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hello, world");
Console.WriteLine("args.Length=" + args.Length);
int i = 0;
foreach (string arg in args)
{
Console.WriteLine("args[i]=" + args[i]);
i++;
}
}
}
}
mcs tamesi9
./tamesi9.exe
hello, world
args.Length=0
那么,
echo 'usi' | ./tamesi9.exe
hello, world
args.Length=0
嗯,命令行参数和标准输入是不同的吗?
那么,
./tamesi9.exe abc def ghi
hello, world
args.Length=3
args[i]=abc
args[i]=def
args[i]=ghi
那么吧。
那好,这样吧。
nano tamesi10
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
string line = Console.ReadLine();
switch (line)
{
case "quit": break;
default: Console.WriteLine("(^q^)"+line); break;
}
}
}
}
}
mcs tamesi10
./tamesi10.exe
start a loop.
好的。
abc
(^q^)abc
好的。
quit
哎呀。
abc
(^q^)
呀呀。复制。
啊,原来如此,即使在 switch 语句中使用 break,它只能跳出 switch 语句,而不能跳出 for 循环。
rm tamesi10
nano tamesi10
像这样。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
string line = Console.ReadLine();
switch (line)
{
case "quit": goto gt_EndLoop;
default: Console.WriteLine("(^q^)"+line); break;
}
}
gt_EndLoop:
Console.WriteLine("finished a loop.");
}
}
}
mcs tamesi10
./tamesi10.exe
start a loop.
abc
(^q^)abc
quit
finished a loop.
这一次顺利了。那么,这个程序能在后台运行吗?
./tamesi10.exe &
[1] 14279
start a loop.
jobs
[1]+ Stopped ./tamesi10.exe
我不明白这个”Stopped”是什么意思。
echo 'usi' | ./tamesi10.exe
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
~略~
【复制】
这是怎么回事啊。
这是什么道理?
尝试在switch语句中加入以下行,会怎么样?
case "": break;
./tamesi10.exe &
[3] 14317
start a loop.
jobs
[1] Stopped ./tamesi10.exe
[2]- Stopped nano tamesi10
[3]+ Stopped ./tamesi10.exe
kill %1
jobs
[1] Terminated ./tamesi10.exe
[2]- Stopped nano tamesi10
[3]+ Stopped ./tamesi10.exe
echo 'usi' | ./tamesi10.exe
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
(^q^)
~中略~
不行吗。
尝试将ReadLine() 替换为Read() 。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
int ch = Console.Read();
Console.WriteLine("(^q^)ch=" + ch);
}
Console.WriteLine("finished a loop.");
}
}
}
mcs tamesi10
tamesi10(15,13): warning CS0162: Unreachable code detected
Compilation succeeded - 1 warning(s)
./tamesi10.exe &
[3] 14482
start a loop.
echo 'usi' | ./tamesi10.exe
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
(^q^)ch=-1
嗯,-1 是什么意思呢。
那就不考虑-1了。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
int ch = Console.Read();
if (-1 != ch)
{
Console.WriteLine("(^q^)ch=" + ch);
}
}
Console.WriteLine("finished a loop.");
}
}
}
顺便说一下,在之前的过程中,出现了一些输出与输入重叠的情况。
root@tk2-217-18401:/home/アカウント名/shogi/ukamuse_sdt4/bin# start a loop.
这个是不是不行呢?
echo 'usi' | ./tamesi10.exe
start a loop.
(^q^)ch=117
(^q^)ch=115
(^q^)ch=105
(^q^)ch=10
嗯,下一步该怎么办?
echo 'abc' | ./tamesi10.exe
没有收到反应。
是什么样的等待状态?
echo 'abc' | ./tamesi10.exe
start a loop.
(^q^)ch=97
(^q^)ch=98
(^q^)ch=99
(^q^)ch=10
你好,标准输入只能运行一次吗?如果输出一次,那么第二次输入就没有效果,这是一种规定吗?
我们尝试使用另一种方法。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
string line = Console.In.ReadLine();
switch (line)
{
case "quit": goto gt_EndLoop;
default: Console.WriteLine("(^q^)line=" + line); break;
}
}
gt_EndLoop:
Console.WriteLine("finished a loop.");
}
}
}
./tamesi10.exe &
echo 'usi' | ./tamesi10.exe
(^q^)line=
(^q^)line=
(^q^)line=
(^q^)line=
(^q^)line=
(^q^)line=
(^q^)line=
~中略~
哦。如果排除null呢?
rm tamesi10
nano tamesi10
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
string line = Console.In.ReadLine();
if (null != line)
{
switch (line)
{
case "quit": goto gt_EndLoop;
default: Console.WriteLine("(^q^)line=" + line); break;
}
}
}
gt_EndLoop:
Console.WriteLine("finished a loop.");
}
}
}
mcs tamesi10
echo 'usi' | ./tamesi10.exe
start a loop.
(^q^)line=usi
abc
def
ghi
echo 'usi' | ./tamesi10.exe
不再起作用了。怎么才能在无限循环中等待呢?
尝试另一种表达方式看看。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
char[] buffer = new char[256];
Console.WriteLine("start a loop.");
for (;;)
{
int result = Console.In.ReadBlock(buffer, 0, 255);
Console.WriteLine("(^q^)result=" + result);
Console.Write("(^q^)buffer=");
foreach (char ch in buffer)
{
Console.Write(ch);
}
Console.WriteLine("(^_^)");
}
Console.WriteLine("finished a loop.");
}
}
}
./tamesi10.exe &
echo 'usi' | ./tamesi10.exe
(^q^)result=0
(^q^)buffer=usi
(^_^)
(^q^)result=0
(^q^)buffer=usi
(^_^)
(^q^)result=0
(^q^)buffer=usi
(^_^)
(^q^)result=0
(^q^)buffer=usi
(^_^)
(^q^)result=0
(^q^)buffer=usi
(^_^)
在Ubuntu/C#中,输入缓冲区是否未被刷新?
输入端的缓冲区是否已被清空?
“自身进程的标准输入输出” (SMDN)
http://smdn.jp/programming/netfx/standard_streams/0_console/
「C#编程竞技爱好者的贴士」 (Qiita)
http://qiita.com/Camypaper/items/de6d576fe5513743a50e
那么,让我们尝试将其重新改写为直到有不同的输入出现才忽略。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
string line_old = "";
Console.WriteLine("start a loop.");
for (;;)
{
string line = Console.ReadLine(); // Ubuntuでは入力がフラッシュされなかった。
if (line!=line_old)
{
Console.WriteLine("(^q^)line=" + line);
line_old = line;
switch (line)
{
case "quit": goto gt_EndLoop;
default: break;
}
}
}
gt_EndLoop:
Console.WriteLine("finished a loop.");
}
}
}
./tamesi10.exe
start a loop.
a
(^q^)line=a
b
(^q^)line=b
c
(^q^)line=c
usi
(^q^)line=usi
quit
(^q^)line=quit
finished a loop.
是的,中奖了!哎呀!为什么还有这样的错误存在。
你安装了mono-complete吗?
那是什么啊!
「如何在 Ubuntu 64 位 v14.04 上安装 Mono?」
我们来试试吧。
sudo apt-get install mono-complete
安装完毕后,行为就变了哈哈哈哈。
using System;
namespace ShogiServer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start a loop.");
for (;;)
{
string line = Console.ReadLine();
Console.WriteLine("(^q^)line=" + line);
switch (line)
{
case "quit": goto gt_EndLoop;
default: break;
}
}
gt_EndLoop:
Console.WriteLine("finished a loop.");
}
}
}
暂时就这样。重新编译并在前台运行时,将会得到预期的结果。
./tamesi10.exe
start a loop.
a
(^q^)line=a
b
(^q^)line=b
c
(^q^)line=c
quit
(^q^)line=quit
finished a loop.
可以将其在后台等待,并尝试向在后台运行的进程的标准输入发送字符吗?
如果做了那样的事情,[Ctrl]+[C] 也变得无效,输入似乎会被吸入将棋服务器。强行结束 PuTTY 并且断开会话可以吗?
我能够重新登录到一个安静的控制台界面,一切都很顺利。
把输出重定向是个好主意吗?
echo 'usi' | ./tamesi10.exe > log1 &
jobs
[1]+ Running echo 'usi' | ./tamesi10.exe > log1 &
哎呀,我第一次看到有人在跑步呢。
ls
nano log1
[ Reading File ]
又被冻结了。屏幕上
[ Reading File ]
只是显示,能进行按键输入吗?
echo 'quit' | ./tamesi10.exe
start a loop.
(^q^)line=quit
finished a loop.
jobs
[1]+ Running echo 'usi' | ./tamesi10.exe > log1 &
有没有办法向正在运行的./tamesi10.exe发送标准输入?
[Ctrl]+[Z]
我不知道什么情况,但我想试试看。 (Wǒ bù , wǒ .)
「What is the difference between Ctrl-z and Ctrl-c in the shell?」 (ask ubuntu)
http://askubuntu.com/questions/510811/what-is-the-difference-between-ctrl-z-and-ctrl-c-in-the-shell
./tamesi10.exe
start a loop.
按下【Ctrl】+【Z】
[1]+ Stopped ./tamesi10.exe
停止了,命令提示符又回来了。
bg 1
[1]+ ./tamesi10.exe &
哦。
fg 1
./tamesi10.exe
回来了。
按下 [Ctrl]+[Z] 键
[1]+ Stopped ./tamesi10.exe
嗯。
fg 1
./tamesi10.exe
usi
(^q^)line=usi
ジョブID が分かってるんだったら手動で「fg 番号」して入力できるが……。
わたしが通信したいんじゃなくて、コンピューター同士に双方向通信させたいんだが、
2つのプロセスを起動させておいて、シェル・スクリプトで fg と bg を使えばいいのだろうか?
标准输入输出通信很难吗?
如果打开端口进行套接字通信会有问题吗……?这个操作好难啊,不知道是怎么回事。
从Shell脚本来看,使用套接字编程是否更简单呢?
とりあえず 将棋サーバーは ポートを開いてバックグラウンドで走らせておいたらいいんじゃないか。
じゃあ、ウェブ・アプリケーション・サーバーは、ポートを開いている実行プログラムに向かって、文字列を投げる方法があるのか調べてみよう。
在PHP或其他编程语言中,能否使用套接字进行通信?
「socket_create_listen」是一個PHP函數,用於創建一個監聽套接字。您可以在PHP手冊的網頁上找到更多關於這個函數的資訊。
连接成功后如何处理套接字?
「fsockopen」(PHP手册)
http://php.net/manual/ja/function.fsockopen.php
【中文翻译】「fsockopen」(PHP手册)
http://php.net/manual/ja/function.fsockopen.php
去買衣服的人,这件就可以了。
「PHP でサーバソケットプログラミング (1)」 (Rainy Day Codings)
http://rainyday.blog.so-net.ne.jp/2007-02-17
服务器接收方面这样可以吗?
那么,就将PHP设置好使吧。
租赁服务器的环境是怎么样的来着?
「费用及服务规格」(樱花互联网)
http://solution.sakura.ad.jp/windows_vps/specification.html
是指让自己去查找 Apache 和 PHP 的版本吗?
php --version
PHP 7.0.15-0ubuntu0.16.04.4 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.15-0ubuntu0.16.04.4, Copyright (c) 1999-2017, by Zend Technologies
哇,PHP 7 哦。
apache2 --version
[Mon Mar 06 02:17:27.188336 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_LOCK_DIR} is not defined
[Mon Mar 06 02:17:27.188706 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_PID_FILE} is not defined
[Mon Mar 06 02:17:27.188743 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_RUN_USER} is not defined
[Mon Mar 06 02:17:27.188765 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_RUN_GROUP} is not defined
[Mon Mar 06 02:17:27.188801 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
[Mon Mar 06 02:17:27.195871 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
[Mon Mar 06 02:17:27.196170 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
[Mon Mar 06 02:17:27.197322 2017] [core:warn] [pid 19747] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
AH00526: Syntax error on line 74 of /etc/apache2/apache2.conf:
Invalid Mutex directory in argument file:${APACHE_LOCK_DIR}
好像没有名为–version的参数。
man apache2
apache2 -v
Server version: Apache/2.4.18 (Ubuntu)
Server built: 2016-07-14T12:32:26
Apache2的版本是2.4.18吗?
那么,PHP的设定已经完成了吗?要试试看吗?
咱们试试 PHP 吧
ブラウザで開いて URLでアクセスすればいいわけなんだが、外に開かれているんだろうか?
ブラウザのURL欄に入れてみる。
http://数字.数字.数字.数字
でた。
Index of /
[ICO] Name Last modified Size Description
[ ] gpskick.php 2015-09-12 03:07 351
[DIR] html/ 2015-09-12 02:40 -
[ ] la.php 2015-09-12 03:14 241
[DIR] tumecheck/ 2015-09-12 03:15 -
[DIR] vscom/ 2015-09-12 03:03 -
这个文件夹在哪里?我对Linux的文件夹结构不太清楚,我可以去搜索一下。
「Ubuntu 服务器Apache」(山本实验室)
http://www.yamamo10.jp/yamamoto/comp/home_server/ubuntu_server/apache/index.php
「Ubuntu 服务器上的Apache」(山本实验室)
http://www.yamamo10.jp/yamamoto/comp/home_server/ubuntu_server/apache/index.php
我們需要查一下,這個頁面應該是在”/var/www/index.html”這樣的地方嗎?
呼呼!
/var/www/html/index.html => 中文: ‘/var/www/html/index.html’
有什么事情发生了。
我看了一下源代码,标签的打法真的不喜欢呢哈哈哈哈哈。
嗨,這看起來不像是頂層。
有一种情况,无法通过FileZilla从外部进行传输。问一下,可以将权限改为 w 吗?
若不改变权限,工作无法进行。需要执行 chmod 命令。
所以,似乎在浏览器中打开PHP没有效果。是没有进行设置吗?
配置 PHP
「【PHP】安装PHP后需要进行的设置」(Qiita)
http://qiita.com/knife0125/items/0e1af52255e9879f9332
在etc文件夹里是否有设置文件?
在 etc 文件夹下有 php 和 php5 两个目录。我觉得其中一个不是 php5。
在 /etc/php/7.0/cli 目录下发现了 php.ini 文件。
哎呀?
「PHP设置」(樱花VPS手册)
http://www.xn--vps-073b3a72a.com/10.html
我的文件夹结构和传递给我的不一样。是在我进行设置之后传递给我的吗?
service httpd restart
如果我按下这个,会启动HTTP守护进程吗?
service httpd restart
Failed to restart httpd.service: Unit httpd.service not found.
いろいろ さっぱり状況が分からんな……。
「7. 网络服务器的设置」(樱花 VPS 手册)
http://www.xn--vps-073b3a72a.com/7.html
「第三步:上傳網頁」(櫻花VPS 使用手冊)
http://www.xn--vps-073b3a72a.com/8.html
/var/www/html 可以被翻译为:网页目录/var/www/html
Sakura VPS 网站的默认目录是 var/www/html。
哎呀!
把改动过的地方恢复原状。
多半是,某种程度上,我感觉我的状态中已经安装了apache2和php7.0,但是它们似乎没有进行任何配置。
然而,如果我卸载/重新安装它们,可能会使已有的配置消失。我不知道当前的状况。
让 Apache 重新启动
我安装了Apache,要试着重新启动一下吗?
「如何在Ubuntu上重新启动Apache的方法和命令」(MiuxMiu)
http://www.miuxmiu.com/archives/2010/03/03/ubuntu_apache_restart_command.html
sudo /etc/init.d/apache2 restart
[ ok ] Restarting apache2 (via systemctl): apache2.service.
似乎很快重新启动了。Apache 是否已启动,但与 PHP 没有连接呢?
Apache的默认页面(称为”It’s works”)可以在html文件夹的下方找到,嗯,原来如此,因为没有进行DNS设置,所以我在这样的子目录中查看页面。
来配置php.ini文件
因为有各种各样的注释,所以要解除这些注释并进行操作。
在备份php.ini文件时,请将其命名为php.ini.original。
;error_log = php_errors.log
我将其逐字符從頭開始拆分,並將目錄修改如下。
error_log = /var/log/php_errors.log
接下来,
;mbstring.language = Japanese
他脱下了脑袋上的分号。
mbstring.language = Japanese
次に、
;mbstring.internal_encoding =
好的,我将其翻译成中文:
这样,我进行了改变。
mbstring.internal_encoding = UTF-8
接下来,
;mbstring.http_input =
这是改变后的方式。
mbstring.http_input = auto
接下来,
;mbstring.detect_order = auto
为了保持原汁原味,以下是对此句子的中文本地化改写:
这样做朝这个方向改变了。
mbstring.detect_order = auto
接下来,
expose_php = On
我改成了以下方式。
expose_php = Off
「关闭 expose_php = off 的设置」(足立工程师的编程日记)
https://www.deep-deep.jp/blog_engineer/archives/3793
接下来,使用FileZilla将配置文件传输到服务器上……每次都使用root用户更改权限,
然后在PuTTY中输入以下命令。
service httpd restart
Failed to restart httpd.service: Unit httpd.service not found.
有什么没有安装呢。
尽管 Apache 已经被安装,但让我们再次尝试安装一次。
yum -y install httpd
The program 'yum' is currently not installed. You can install it by typing:
apt install yum
与说明完全不符合。
让我们安装 yum。
apt install yum
我已经安装了。
yum -y install httpd
There are no enabled repos.
Run "yum repolist all" to see the repos you have.
You can enable repos with yum-config-manager --enable <repo>
不懂。
yum repolist all
repolist: 0
重新启动Apache.
sudo /etc/init.d/apache2 restart
[ ok ] Restarting apache2 (via systemctl): apache2.service.
我能做到。那么你可以这样敲击吗?
sudo /etc/init.d/httpd restart
sudo: /etc/init.d/httpd: command not found
在 init.d 目录下是否有 httpd 命令?
/etc/init.d# ls
apache2 halt networking single
apache-htcacheclean hostname.sh ondemand skeleton
apparmor hwclock.sh plymouth ssh
binfmt-support irqbalance plymouth-log thermald
bootmisc.sh keyboard-setup pppd-dns udev
cgmanager killprocs procps ufw
cgproxy kmod rc umountfs
checkfs.sh memcached rc.local umountnfs.sh
checkroot-bootclean.sh mountall-bootclean.sh rcS umountroot
checkroot.sh mountall.sh README urandom
console-setup mountdevsubfs.sh reboot uuidd
cron mountkernfs.sh resolvconf x11-common
dbus mountnfs-bootclean.sh rsync
dns-clean mountnfs.sh rsyslog
grub-common mysql sendsigs
没有。没有超级文本传输协议。
为什么没有httpd?
「Can’t find httpd.conf」 (ask ubuntu)
http://askubuntu.com/questions/652095/cant-find-httpd-conf
/etc/apache2# ls
apache2.conf conf-enabled magic mods-enabled sites-available
conf-available envvars mods-available ports.conf sites-enabled
sudo /etc/apache2/apache2.conf restart
sudo: /etc/apache2/apache2.conf: command not found
不行。
index.php 网页
<?php
echo 'hello, shogi world1';
这个内容会直接显示出来。那么,换成HTML呢? HTML能够正常显示。
echo "<?php phpinfo();"
在命令行中输入时没有任何反应。
由于当前环境的问题,我们需要重新安装。
「PHP配置」(樱花VPS配置手册)
http://www.sakura-vps.net/php-settings-for-sakura-vps/
yum -y install php php-mbstring php-mysql
There are no enabled repos.
Run "yum repolist all" to see the repos you have.
You can enable repos with yum-config-manager --enable <repo>
「【適合新手】当PHP在浏览器中无法正确显示时的应对方法」(n2p博客)
php index.php
hello, shogi world1
这个在动。那么,让我们尝试执行phpinfo()。
看起来显示出来了。
那么,需要权限吗?
ls -an
-rw-r--r-- 1 0 0 11510 Sep 12 2015 index.html
-rw-rw-r-- 1 1000 1000 21 Mar 6 04:04 index.php
html可以看得到呢。
Apache的配置中是否没有写入了PHP呢?
在浏览器中打开
<?php phpinfo();
原样显示。
Document Roots
By default, Ubuntu does not allow access through the web browser to any file apart of those located in /var/www, public_html directories (when enabled) and /usr/share (for web applications). If your site is using a web document root located elsewhere (such as in /srv) you may need to whitelist your document root directory in /etc/apache2/apache2.conf.
The default Ubuntu document root is /var/www/html. You can make your own virtual hosts under /var/www. This is different to previous releases which provides better security out of the box.
「PHP代码未执行而变成了注释」
那么,要删除php5吗?
“安装PHP5.5或PHP5.6” (Qiita)
sudo yum remove php-*
似乎没有达成一致。
使用PHP是否有免费的选项吗?
「UbuntuサーバからPHP5.6を完全に削除」 (エンジニア足立のコーディング日記)
https://www.deep-deep.jp/blog_engineer/archives/4168
如果完全删除的话
sudo apt-get –purge remove php5.6
E: Invalid operation –purge
不动。
只保留配置文件的情况下
sudo apt-get remove php5.6
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'php5.6-json' for regex 'php5.6'
Note, selecting 'php5.6-common' for regex 'php5.6'
Package 'php5.6-common' is not installed, so not removed
Package 'php5.6-json' is not installed, so not removed
The following packages were automatically installed and are no longer required:
libssl-dev libssl-doc php-cli php-common php-pear php-xml php7.0-cli php7.0-common
php7.0-json php7.0-opcache php7.0-readline php7.0-xml pkg-php-tools shtool
zlib1g-dev
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
我动了。可是,只是零而已。
我认为是Apache的配置问题,因为从命令行上可以运行PHP。
让我们在Apache的配置文件中设置PHP
「向 Apache 添加 php7 模块并注册 .php 文件扩展名」(Admin Web)
https://www.adminweb.jp/apache/php/index1.html
由于没有 httpd.conf 文件,所以
让我们打开/etc/apache2/apache2.conf来看一看。
解释完全不同。通过
“Ubuntu上的Apache配置摘要” (freefielder.jp)
http://freefielder.jp/blog/2012/12/ubuntu-apache.html
找/etc/apache2/mods-available/php5.conf文件。
有的。
有的,但是叫php5这个名字可以吗?
php_admin_flag engine Off
决定在标有这样写的地方前加入 #。
重新启动 Apache。
sudo service apache2 restart
浏览器没有变化。
「Ubuntu 16.04 安装(6)Apache、PHP」(kashi的日记)http://verifiedby.me/adiary/086
/etc/apache2/sites-available# ls
000-default.conf 000-default.conf.bak default-ssl.conf
嗯,看起来不相关。
【Ubuntu】将 PHP 5.6 升级到 PHP 7 (Sukohi的技术博客!!)
http://sukohi.blogspot.jp/2016/01/ubuntuphp-56-php-7.html
搬家。
/etc/apache2/mods-enabled 可以被改写为:
/etc/apache2/mods-enabled
ls -an
total 8
drwxr-xr-x 2 0 0 4096 Mar 4 21:09 .
drwxr-xr-x 8 0 0 4096 Mar 4 21:13 ..
lrwxrwxrwx 1 0 0 36 Sep 12 2015 access_compat.load -> ../mods-available/access_compat.load
lrwxrwxrwx 1 0 0 28 Sep 12 2015 alias.conf -> ../mods-available/alias.conf
lrwxrwxrwx 1 0 0 28 Sep 12 2015 alias.load -> ../mods-available/alias.load
lrwxrwxrwx 1 0 0 33 Sep 12 2015 auth_basic.load -> ../mods-available/auth_basic.load
lrwxrwxrwx 1 0 0 33 Sep 12 2015 authn_core.load -> ../mods-available/authn_core.load
lrwxrwxrwx 1 0 0 33 Sep 12 2015 authn_file.load -> ../mods-available/authn_file.load
lrwxrwxrwx 1 0 0 33 Sep 12 2015 authz_core.load -> ../mods-available/authz_core.load
lrwxrwxrwx 1 0 0 33 Sep 12 2015 authz_host.load -> ../mods-available/authz_host.load
lrwxrwxrwx 1 0 0 33 Sep 12 2015 authz_user.load -> ../mods-available/authz_user.load
lrwxrwxrwx 1 0 0 32 Sep 12 2015 autoindex.conf -> ../mods-available/autoindex.conf
lrwxrwxrwx 1 0 0 32 Sep 12 2015 autoindex.load -> ../mods-available/autoindex.load
lrwxrwxrwx 1 0 0 30 Sep 12 2015 deflate.conf -> ../mods-available/deflate.conf
lrwxrwxrwx 1 0 0 30 Sep 12 2015 deflate.load -> ../mods-available/deflate.load
lrwxrwxrwx 1 0 0 26 Sep 12 2015 dir.conf -> ../mods-available/dir.conf
lrwxrwxrwx 1 0 0 26 Sep 12 2015 dir.load -> ../mods-available/dir.load
lrwxrwxrwx 1 0 0 26 Sep 12 2015 env.load -> ../mods-available/env.load
lrwxrwxrwx 1 0 0 29 Sep 12 2015 filter.load -> ../mods-available/filter.load
lrwxrwxrwx 1 0 0 27 Sep 12 2015 mime.conf -> ../mods-available/mime.conf
lrwxrwxrwx 1 0 0 27 Sep 12 2015 mime.load -> ../mods-available/mime.load
lrwxrwxrwx 1 0 0 34 Sep 12 2015 mpm_prefork.conf -> ../mods-available/mpm_prefork.conf
lrwxrwxrwx 1 0 0 34 Sep 12 2015 mpm_prefork.load -> ../mods-available/mpm_prefork.load
lrwxrwxrwx 1 0 0 34 Sep 12 2015 negotiation.conf -> ../mods-available/negotiation.conf
lrwxrwxrwx 1 0 0 34 Sep 12 2015 negotiation.load -> ../mods-available/negotiation.load
lrwxrwxrwx 1 0 0 30 Sep 12 2015 rewrite.load -> ../mods-available/rewrite.load
lrwxrwxrwx 1 0 0 31 Sep 12 2015 setenvif.conf -> ../mods-available/setenvif.conf
lrwxrwxrwx 1 0 0 31 Sep 12 2015 setenvif.load -> ../mods-available/setenvif.load
lrwxrwxrwx 1 0 0 29 Sep 12 2015 status.conf -> ../mods-available/status.conf
lrwxrwxrwx 1 0 0 29 Sep 12 2015 status.load -> ../mods-available/status.load
看起来与PHP5无关。
让我们删除php5文件夹试试看。
有一个名为 etc/php5 的目录。删除它。
rm -rf php5/
重新启动Apache。
sudo service apache2 restart
这样还不行。
httpd.conf 在哪里呢?
「在Windows 10上将PHP 7.0安装到Apache 2.4」(博客)
http://weblog.4141.biz/?p=359
由于是Windows的设置,所以不相配。
「在Ubuntu服务器上,Apache2上的httpd.conf文件的内容是什么?」
尝试删除/etc/apache2/mods-available目录中的php5文件。
rm php5.conf
rm php5.load
重启Apache。
sudo service apache2 restart
这样还不行。
sudo apt-get remove php
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package 'php' is not installed, so not removed
The following packages were automatically installed and are no longer required:
libssl-dev libssl-doc php-cli php-common php-pear php-xml php7.0-cli php7.0-common php7.0-json
php7.0-opcache php7.0-readline php7.0-xml pkg-php-tools shtool zlib1g-dev
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
不行。
「Apache 2.x (适用于 Unix 系统)」(PHP 文档)
http://php.net/manual/zh/install.unix.apache2.php
不对。
「Debian GNU/Linux 安装指南」(PHP文档)
http://php.net/manual/zh/install.unix.debian.php
apt-get install php5-common libapache2-mod-php5 php5-cli
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package libapache2-mod-php5 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
Package php5-cli is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
php7.0-cli:i386 php7.0-cli
Package php5-common is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'php5-common' has no installation candidate
E: Package 'libapache2-mod-php5' has no installation candidate
E: Package 'php5-cli' has no installation candidate
嗯,出现了一些错误。
/etc/init.d/apache2 stop
[ ok ] Stopping apache2 (via systemctl): apache2.service.
停止了Apache就无法访问网站。
/etc/init.d/apache2 start
[ ok ] Starting apache2 (via systemctl): apache2.service.
重新启动Apache后,可以访问网站,但PHP的源代码直接被输出。
apt-cache search php5
bluefish - advanced Gtk+ text editor for web and software development
phing - PHP5 project build system based on Apache Ant
php-auth - Creating an authentication system
php-doc - Documentation for PHP5
php-http-request2 - Provides an easy way to perform HTTP requests
php-letodms-lucene - Document management system - Fulltext search
php-memcache - memcache extension module for PHP5
php-memcached - memcached extension module for PHP5, uses libmemcached
php-net-dns2 - PHP5 Resolver library used to communicate with a DNS server
phpunit - Unit testing suite for PHP5
aptitude search php5
The program 'aptitude' is currently not installed. You can install it by typing:
apt install aptitude
使用PHP脚本进行操作 (服务器世界)
https://www.server-world.info/query?os=Debian_8&p=httpd&f=3
aptitude -y install php5 php5-cgi libapache2-mod-php5 php5-common php-pear
The program 'aptitude' is currently not installed. You can install it by typing:
apt install aptitude
让我们安装aptitude。
在Ubuntu 10.10和11.04的64位系统中安装aptitude。
sudo apt-get install aptitude
可能成功安装了吗?
aptitude -y install php5 php5-cgi libapache2-mod-php5 php5-common php-pear
这次是在动的。
在Apache的配置文件中,将PHP的文件扩展名与其关联。
nano /etc/apache2/mods-enabled/mime.conf
在第220行附近进行追加记录。
# PHP extension
AddHandler php5-script .php
systemctl restart apache2
不可以。
apt-get install php5-common libapache2-mod-php5 php5-cli
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package libapache2-mod-php5 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
Package php5-cli is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
php7.0-cli:i386 php7.0-cli
Package php5-common is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'php5-common' has no installation candidate
E: Package 'libapache2-mod-php5' has no installation candidate
E: Package 'php5-cli' has no installation candidate
出现错误。
「Debian 上安装 PHP + Apache – Linux 入门」(Webkaru 网站)
http://webkaru.net/linux/debian-php-apache-install/
apt-get install apache2 php5
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package php5 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'php5' has no installation candidate
出现了错误。
php -v
-su: /usr/bin/php: No such file or directory
出现错误。
php info.php
-su: /usr/bin/php: No such file or directory
是说没有PHP吗?
让我们安装PHP7
「在Debian(jessie)上安装PHP 7的方法」(Promise Land)
apt-get install php
安装。PHP 7 相当于用指定命令安装的PHP版本。
php -v
PHP 7.0.15-0ubuntu0.16.04.4 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.15-0ubuntu0.16.04.4, Copyright (c) 1999-2017, by Zend Technologies
暂时已安装了PHP7。
如何卸载Apache和PHP?
在Debian系统上完全卸载Apache2,然后重新安装。
首先,通过字符串搜索来查找相关的软件包。
dpkg --get-selections | grep apache
apache2 install
apache2-bin install
apache2-data install
apache2-utils install
libapache2-mod-php5 install
删除找到的软件包
apt-get remove --purge apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php5
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.1-0 ssl-cert
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
apache2* apache2-bin* apache2-data* apache2-utils* libapache2-mod-php5*
0 upgraded, 0 newly installed, 5 to remove and 0 not upgraded.
After this operation, 5,383 kB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 45809 files and directories currently installed.)
Removing apache2 (2.4.18-2ubuntu3.1) ...
Purging configuration files for apache2 (2.4.18-2ubuntu3.1) ...
dpkg: warning: while removing apache2, directory '/var/www/html' not empty so not removed
Removing apache2-bin (2.4.18-2ubuntu3.1) ...
Removing apache2-data (2.4.18-2ubuntu3.1) ...
Removing apache2-utils (2.4.18-2ubuntu3.1) ...
Removing libapache2-mod-php5 (5.5.9+dfsg-1ubuntu4.21) ...
Purging configuration files for libapache2-mod-php5 (5.5.9+dfsg-1ubuntu4.21) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for ufw (0.35-0ubuntu2) ...
dpkg --get-selections | grep apache
我删除了与 Apache 相关的软件包。
然后,我会搜索与 PHP 相关的软件包。
dpkg --get-selections | grep php
php install
php-common install
php-pear deinstall
php5-cli deinstall
php5-common install
php5-json deinstall
php5-memcached deinstall
php5-mysql deinstall
php5-readline deinstall
php7.0 install
php7.0-cli install
php7.0-common install
php7.0-fpm install
php7.0-json install
php7.0-opcache install
php7.0-readline install
php7.0-xml deinstall
删除找到的包
apt-get remove --purge php php-common php-pear php5-cli php5-common php5-json php5-memcached php5-mysql php5-readline php7.0 php7.0-cli php7.0-common php7.0-fpm php7.0-json php7.0-opcache php7.0-readline php7.0-xml
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.1-0 ssl-cert
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
php* php-common* php-pear* php5-cli* php5-common* php5-json* php5-memcached* php5-mysql* php5-readline*
php7.0* php7.0-cli* php7.0-common* php7.0-fpm* php7.0-json* php7.0-opcache* php7.0-readline* php7.0-xml*
0 upgraded, 0 newly installed, 17 to remove and 0 not upgraded.
After this operation, 14.1 MB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 45161 files and directories currently installed.)
Removing php (1:7.0+35ubuntu6) ...
Removing php7.0 (7.0.15-0ubuntu0.16.04.4) ...
Removing php7.0-fpm (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-fpm (7.0.15-0ubuntu0.16.04.4) ...
dpkg: warning: while removing php7.0-fpm, directory '/etc/php/7.0/fpm/conf.d' not empty so not removed
Removing php7.0-cli (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-cli (7.0.15-0ubuntu0.16.04.4) ...
dpkg: warning: while removing php7.0-cli, directory '/etc/php/7.0/cli/conf.d' not empty so not removed
Removing php7.0-readline (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-readline (7.0.15-0ubuntu0.16.04.4) ...
Removing php7.0-opcache (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-opcache (7.0.15-0ubuntu0.16.04.4) ...
Removing php-pear (1:1.10.1+submodules+notgz-6) ...
Purging configuration files for php-pear (1:1.10.1+submodules+notgz-6) ...
Removing php5-cli (5.5.9+dfsg-1ubuntu4.21) ...
Purging configuration files for php5-cli (5.5.9+dfsg-1ubuntu4.21) ...
Removing php5-common (5.5.9+dfsg-1ubuntu4.21) ...
Purging configuration files for php5-common (5.5.9+dfsg-1ubuntu4.21) ...
dpkg: warning: while removing php5-common, directory '/usr/share/doc/php5-common' not empty so not removed
Removing php5-json (1.3.2-2build1) ...
Purging configuration files for php5-json (1.3.2-2build1) ...
dpkg: warning: while removing php5-json, directory '/usr/lib/php5/20121212' not empty so not removed
Removing php5-memcached (2.1.0-6build1) ...
Purging configuration files for php5-memcached (2.1.0-6build1) ...
dpkg: warning: while removing php5-memcached, directory '/usr/share/php/.registry/.channel.pecl.php.net' not empty so not removed
Removing php5-mysql (5.5.9+dfsg-1ubuntu4.21) ...
Purging configuration files for php5-mysql (5.5.9+dfsg-1ubuntu4.21) ...
Removing php5-readline (5.5.9+dfsg-1ubuntu4.21) ...
Purging configuration files for php5-readline (5.5.9+dfsg-1ubuntu4.21) ...
Removing php7.0-json (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-json (7.0.15-0ubuntu0.16.04.4) ...
Removing php7.0-common (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-common (7.0.15-0ubuntu0.16.04.4) ...
dpkg: warning: while removing php7.0-common, directory '/etc/php/7.0/mods-available' not empty so not removed
Removing php7.0-xml (7.0.15-0ubuntu0.16.04.4) ...
Purging configuration files for php7.0-xml (7.0.15-0ubuntu0.16.04.4) ...
Removing php-common (1:35ubuntu6) ...
Purging configuration files for php-common (1:35ubuntu6) ...
Processing triggers for man-db (2.7.5-1) ...
dpkg --get-selections | grep php
我已经删除了与Apache相关的软件包。
接下来重新安装。
apt-get install apache2 php
让Apache启动一下。
/etc/init.d/apache2 start
[ ok ] Starting apache2 (via systemctl): apache2.service.
当访问404 Not Found时,如果改为访问其上一层目录而不是html文件夹,将会显示”It works!”的页面。
index.php 依然直接显示源代码。
另外设置
nano /etc/apache2/mods-enabled/mime.conf
据报道,据说在第220行左右有追加内容。
# PHP extension
AddHandler php5-script .php
重新启动 Apache。
/etc/init.d/apache2 start
[ ok ] Starting apache2 (via systemctl): apache2.service.
PHP的原始碼保持不變。
「使用 PHP 脚本」(服务器世界)
安装 PHP。
apt-get -y install php php-cgi libapache2-mod-php php-common php-pear php-mbstring
重新启动Apache。
sudo /etc/init.d/apache2 restart
[ ok ] Restarting apache2 (via systemctl): apache2.service.
哎呀?phpinfo() 正常运行了。
那么决定的关键是,
-
- アパッチ アンインストール
-
- PHP アンインストール
-
- アパッチとPHPを同時にインストール
-
- apt-get -y install php php-cgi libapache2-mod-php php-common php-pear php-mbstring
- アパッチ再起動「sudo /etc/init.d/apache2 restart」
这附近吗?中途目录层次也改变了。
我可以在浏览器中使用URL访问并传递GET查询字符串给程序吗?
「使用HTTP进行的套接字通信」
服务器方面想要的。
「【CakePHP】获取请求的方法」(Qitta)
http://qiita.com/kazu56/items/7d344ccef56deef66a7a
暂时尝试使用 PHP 获取 GET 查询字符串。
http://a.b.c.d/html/?shogi=sfen 3/1p1/1P1/3 w - 1 moves
就像那种感觉。
$shogi = $this->request->query('shogi');
这是什么东西,不行啊。
获取整个查询字符串。
「urldecode」(PHP手册)
http://php.net/manual/zh/function.urldecode.php
比如这样的感觉。
tamesi1.php可以转述为:tamesi1.php
<?php
$query = urldecode($_SERVER['QUERY_STRING']);
echo '(^q^)' . $query . '<br />';
echo 'クリックしろだぜ☆m9(^~^)!<br />';
echo '<a href="http://999.999.999.999/tamesi1.php?shogi=sfen 3/1p1/1P1/3 w - 1 moves">http://999.999.999.999/?shogi=sfen 3/1p1/1P1/3 w - 1 moves</a><br />';
所以,如果服务器端正在运行程序,我们要如何传递这个字符串呢?假设端口号已经开放,我们只需写入吗?能使用PHP实现吗?
将数据从exe传递给php。
我们来研究一下进程间通信吧。
《消息队列的使用方法(C语言和PHP进行进程间通信)》(Linux安装备忘录)
消息队列也有吗?
消息队列
暂时先从C#方面进行调查。
「在C#中向消息隊列發送消息」(ITLAB51.COM)
http://www.itlab51.com/?p=4111
在Windows的搜索框中键入“计算机管理”。
[服务和应用程序] – [消息队列] – [专用队列]
现在是空的,但似乎可以在这里留下信息。
待会儿试试看吧。
通过C#消息队列接收消息 (ITLAB51.COM)
看起来必须先创建消息队列。
「 在 C# 的消息隊列中創建專用隊列」(ITLAB51.COM)
好的,我在Windows中确认了。
C# 示例程式
using System;
using System.Messaging; // [References] - [Add Reference]
namespace MsgQueue
{
/// <summary>
/// キュー(メッセージ箱)に送り込んだ情報があるか確認する方法。
/// (1) Windowsの検索ボックスに「コンピューターの管理」と入力。
/// (2) [サービスとアプリケーション] - [メッセージ キュー] を開く。
/// (3) [F5]キーで更新。
/// </summary>
class Program
{
public const string QUEUE_NAME = @".\Private$\testqueue";
static void Main(string[] args)
{
for (;;)
{
Console.WriteLine(@"選べだぜ☆(^~^)
1 : メッセージ箱 作成
2 : メッセージ 送信
3 : メッセージ 受信
4 : メッセージ箱 削除
quit: 終了
");
int category = 0;
for (;;)
{
string line = Console.ReadLine();
switch (line)
{
case "1": category = 1; goto gt_EndLoop1;
case "2": category = 2; goto gt_EndLoop1;
case "3": category = 3; goto gt_EndLoop1;
case "4": category = 4; goto gt_EndLoop1;
case "quit": goto gt_Quit;
default: break;
}
}
gt_EndLoop1:
;
switch (category)
{
case 1:
{
if (MessageQueue.Exists(QUEUE_NAME))
{
Console.WriteLine("キュー["+ QUEUE_NAME + "]は既存だぜ☆(^~^)");
}
else
{
// キュー名は、大文字で指定しても小文字になる
MessageQueue.Create(QUEUE_NAME);
}
}
break;
case 2:
{
MessageQueue mq = new MessageQueue((@".\Private$\testqueue"));
Message msg = new Message();
msg.Body = "テストメッセージだぜ☆(^▽^)";
msg.Label = "テストだぜ☆(^~^)";
mq.Send(msg);
}
break;
case 3:
{
MessageQueue mq = new MessageQueue((@".\Private$\testqueue"));
System.Messaging.Message msg = new System.Messaging.Message();
msg = mq.Receive();
msg.Formatter = new XmlMessageFormatter(new string[] { "System.String, mscorlib" });
Console.WriteLine(msg.Body.ToString());
}
break;
case 4:
{
if (MessageQueue.Exists(QUEUE_NAME))
{
MessageQueue.Delete(QUEUE_NAME);
}
else
{
Console.WriteLine("キュー[" + QUEUE_NAME + "]なんか無いぜ☆(^~^)");
}
}
break;
}
}
gt_Quit:
;
}
}
}
不妨也试试Ubuntu吧。
nano MsgQueue.cs
mcs MsgQueue.cs
MsgQueue.cs(2,14): error CS0234: The type or namespace name `Messaging' does not exist in the namespace `System'. Are you missing an assembly reference?
Compilation failed: 1 error(s), 0 warnings
怎么样才能添加 System.Messaging 的引用?
「「○○○.dllを参照に追加します」的意思是什么?」 (DOBON.NET)
http://dobon.net/vb/dotnet/help/addreference.html
「/参考」(MSDN)
https://msdn.microsoft.com/zh-CN/library/2b07fd84(v=vs.100).aspx
那么,这样就可以了吗?
mcs /reference:messaging.dll MsgQueue.cs
error CS0006: Metadata file `messaging.dll' could not be found
Compilation failed: 1 error(s), 0 warnings
嘛,沒有.dll檔啊。該怎麼辦呢……。
「系统消息 DLL 丢失?」 (stackoverflow)
http://stackoverflow.com/questions/13409342/system-messaging-dll-missing
好的。
mcs /reference:System.Messaging.dll MsgQueue.cs
成功了吗?
./MsgQueue.exe
選べだぜ☆(^~^)
1 : メッセージ箱 作成
2 : メッセージ 送信
3 : メッセージ 受信
4 : メッセージ箱 削除
quit: 終了
1
選べだぜ☆(^~^)
1 : メッセージ箱 作成
2 : メッセージ 送信
3 : メッセージ 受信
4 : メッセージ箱 削除
quit: 終了
2
Insert: Mono.Messaging.RabbitMQ.MessagingContext
Unhandled Exception:
System.Messaging.MessageQueueException: Unable to connect to Queue: localhost\private$\testqueue, Error: None of the specified endpoints were reachable
at System.Messaging.MessageQueue.Send (System.Object obj) <0x40f79d90 + 0x00227> in <filename unknown>:0
at (wrapper remoting-invoke-with-check) System.Messaging.MessageQueue:Send (object)
at MsgQueue.Program.Main (System.String[] args) <0x40f46d50 + 0x00233> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Messaging.MessageQueueException: Unable to connect to Queue: localhost\private$\testqueue, Error: None of the specified endpoints were reachable
at System.Messaging.MessageQueue.Send (System.Object obj) <0x40f79d90 + 0x00227> in <filename unknown>:0
at (wrapper remoting-invoke-with-check) System.Messaging.MessageQueue:Send (object)
at MsgQueue.Program.Main (System.String[] args) <0x40f46d50 + 0x00233> in <filename unknown>:0
这是什么鬼~。
指定的任何节点都无法连接。
使用单例模式解决问题?
「Linux的消息队列(IPC)」(楽吾楽,重复自己)
http://blogs.yahoo.co.jp/ichi0346/34314386.html
“Linux的消息队列(IPC)”(楽吾楽,独自複製)
http://blogs.yahoo.co.jp/ichi0346/34314386.html
嗯,出错了哦。
cat /proc/sys/fs/mqueue/msg_max
10
cat /proc/sys/fs/mqueue/msgsize_max
8192
cat /proc/sys/fs/mqueue/queues_max
256
Qiita的网关超时了,需要换一篇文章。
<第二部分>