MongoDB源码分析——mongo主程序入口分析

时间:2023-03-09 17:21:59
MongoDB源码分析——mongo主程序入口分析

Edit
源码版本为MongoDB 2.6分支

mongo主程序入口分析

mongo是MongoDB提供的一个执行JavaScript脚本的客户端工具,可以用来和服务端交互,2.6版本的MongoDB已经是使用了V8 JS引擎,由于本人对JS几乎没研究,所以本篇只是大概研究一下执行过程,对于JS的东西就先略过。

mongo的main函数在dbshell.cpp文件中,同mongod一样提供了Windows和Linux两个版本,然后调用int _main( int argc, char* argv[], char **envp )函数。

mongo::isShell = true;  //用来判断是否启动shell
setupSignals(); //设置Linux信号处理函数 mongo::shell_utils::RecordMyLocation( argv[ ] ); shellGlobalParams.url = "test";//默认连接到test数据库
//同mongod,根据命令行初始化全局变量
mongo::runGlobalInitializersOrDie(argc, argv, envp); // hide password from ps output
for ( int i = ; i < (argc-); ++i ) {
if ( !strcmp(argv[i], "-p") || !strcmp( argv[i], "--password" ) ) {
char* arg = argv[i + ];
while ( *arg ) {
*arg++ = 'x';
}
}
} if (!mongo::serverGlobalParams.quiet)
cout << "MongoDB shell version: " << mongo::versionString << endl; mongo::StartupTest::runTests();
...
//如果没有配置nodb,则生成连接服务器的js脚本,现在还不会执行
//在之后初始化V8引擎后才会连接服务器
if (!shellGlobalParams.nodb) { // connect to db
stringstream ss;
if (mongo::serverGlobalParams.quiet)
ss << "__quiet = true;";
ss << "db = connect( \""
<< fixHost(shellGlobalParams.url, shellGlobalParams.dbhost, shellGlobalParams.port)
<< "\")"; mongo::shell_utils::_dbConnect = ss.str();
//如果需要认证,则让用户输入密码
if (shellGlobalParams.usingPassword && shellGlobalParams.password.empty()) {
shellGlobalParams.password = mongo::askPassword();
}
}

下面部分代码生成一堆JS验证信息,同样验证也会在V8初始化之后进行(在mongo::shell_utils::initScope函数中)。

stringstream authStringStream;
authStringStream << "(function() { " << endl;
if (!shellGlobalParams.authenticationMechanism.empty()) {
authStringStream << "DB.prototype._defaultAuthenticationMechanism = \"" <<
escape(shellGlobalParams.authenticationMechanism) << "\";" << endl;
} if (!shellGlobalParams.gssapiServiceName.empty()) {
authStringStream << "DB.prototype._defaultGssapiServiceName = \"" <<
escape(shellGlobalParams.gssapiServiceName) << "\";" << endl;
} if (!shellGlobalParams.nodb && shellGlobalParams.username.size()) {
authStringStream << "var username = \"" << escape(shellGlobalParams.username) << "\";" <<
endl;
if (shellGlobalParams.usingPassword) {
authStringStream << "var password = \"" << escape(shellGlobalParams.password) << "\";"
<< endl;
}
if (shellGlobalParams.authenticationDatabase.empty()) {
authStringStream << "var authDb = db;" << endl;
}
else {
authStringStream << "var authDb = db.getSiblingDB(\""
<< escape(shellGlobalParams.authenticationDatabase) << "\");" << endl;
}
authStringStream << "authDb._authOrThrow({ " <<
saslCommandUserFieldName << ": username ";
if (shellGlobalParams.usingPassword) {
authStringStream << ", " << saslCommandPasswordFieldName << ": password ";
} if (!shellGlobalParams.gssapiHostName.empty()) {
authStringStream << ", " << saslCommandServiceHostnameFieldName << ": \""
<< escape(shellGlobalParams.gssapiHostName) << '"' << endl;
}
authStringStream << "});" << endl;
}
authStringStream << "}())";
mongo::shell_utils::_dbAuth = authStringStream.str();

上面部分一如既往的进行全局变量初始化,之后下面部分将会初始化V8引擎

mongo::ScriptEngine::setConnectCallback( mongo::shell_utils::onConnect );
mongo::ScriptEngine::setup();
mongo::globalScriptEngine->setScopeInitCallback( mongo::shell_utils::initScope );
auto_ptr< mongo::Scope > scope( mongo::globalScriptEngine->newScope() );
shellMainScope = scope.get();

首先初始化ScriptEngine,然后设置Scope初始化回调函数initScope ,之后调用newScope()函数返回V8Scope对象,同时连接数据库,根据之前生成的信息进行验证。

V8初始化之后首先会去执行mongorc.js配置文件,这个有点像vim的.vimrc文件,所以一些必须要先执行的代码可以写到mongorc.js文件中。

std::string rcGlobalLocation;
#ifndef _WIN32
rcGlobalLocation = "/etc/mongorc.js" ;
#else
wchar_t programDataPath[MAX_PATH];
if ( S_OK == SHGetFolderPathW(NULL,
CSIDL_COMMON_APPDATA,
NULL,
,
programDataPath) ) {
rcGlobalLocation = str::stream() << toUtf8String(programDataPath)
<< "\\MongoDB\\mongorc.js";
}
#endif
if ( !rcGlobalLocation.empty() && ::mongo::shell_utils::fileExists(rcGlobalLocation) ) {
if ( ! scope->execFile( rcGlobalLocation , false , true ) ) {
cout << "The \"" << rcGlobalLocation << "\" file could not be executed" << endl;
}
}

从代码中可以看出mongorc.js文件在Windows下路径是%appdata%\MongoDB\mongorc.js,在Linux下面是”/etc/mongorc.js”。

之后一段不是很重要的信息直接略过,来看最后一部分,完成之前的所有配置之后,肯定是启动shell,等待用户输入,执行命令。

    shellHistoryInit();

    string prompt;
int promptType; while ( ) {
...
char * line = shellReadline( prompt.c_str() );
...
bool wascmd = false;
{
string cmd = linePtr;
if ( cmd.find( " " ) > )
cmd = cmd.substr( , cmd.find( " " ) );
//判断用户输入是否是命令,如果是则去执行命令
if ( cmd.find( "\"" ) == string::npos ) {
try {
scope->exec( (string)"__iscmd__ = shellHelper[\"" + cmd + "\"];" , "(shellhelp1)" , false , true , true );
if ( scope->getBoolean( "__iscmd__" ) ) {
scope->exec( (string)"shellHelper( \"" + cmd + "\" , \"" + code.substr( cmd.size() ) + "\");" , "(shellhelp2)" , false , true , false );
wascmd = true;
}
}
catch ( std::exception& e ) {
cout << "error2:" << e.what() << endl;
wascmd = true;
}
}
}
//如果不是命令则执行js脚本。
if ( ! wascmd ) {
try {
if ( scope->exec( code.c_str() , "(shell)" , false , true , false ) )
scope->exec( "shellPrintHelper( __lastres__ );" , "(shell2)" , true , true , false );
}
catch ( std::exception& e ) {
cout << "error:" << e.what() << endl;
}
}
//记录用户输入历史
shellHistoryAdd( code.c_str() );
free( line );
} shellHistoryDone();

上面的代码中我删除了前面部分的判断逻辑,只保留了js的执行部分。可以看到整个流程的核心是scope->exec(…)函数,scope其实是V8Scope对象。

由于目前js方面水平有限,mongo的启动就暂时分析到此,以后有空再深入研究一下V8引擎和js部分的代码。

%23%23%20mongo%u4E3B%u7A0B%u5E8F%u5165%u53E3%u5206%u6790%0A%0Amongo%u662FMongoDB%u63D0%u4F9B%u7684%u4E00%u4E2A%u6267%u884CJavaScript%u811A%u672C%u7684%u5BA2%u6237%u7AEF%u5DE5%u5177%uFF0C%u53EF%u4EE5%u7528%u6765%u548C%u670D%u52A1%u7AEF%u4EA4%u4E92%uFF0C2.6%u7248%u672C%u7684MongoDB%u5DF2%u7ECF%u662F%u4F7F%u7528%u4E86V8%20JS%u5F15%u64CE%uFF0C%u7531%u4E8E%u672C%u4EBA%u5BF9JS%u51E0%u4E4E%u6CA1%u7814%u7A76%uFF0C%u6240%u4EE5%u672C%u7BC7%u53EA%u662F%u5927%u6982%u7814%u7A76%u4E00%u4E0B%u6267%u884C%u8FC7%u7A0B%uFF0C%u5BF9%u4E8EJS%u7684%u4E1C%u897F%u5C31%u5148%u7565%u8FC7%u3002%0A%0Amongo%u7684main%u51FD%u6570%u5728dbshell.cpp%u6587%u4EF6%u4E2D%uFF0C%u540Cmongod%u4E00%u6837%u63D0%u4F9B%u4E86Windows%u548CLinux%u4E24%u4E2A%u7248%u672C%uFF0C%u7136%u540E%u8C03%u7528int%20_main%28%20int%20argc%2C%20char*%20argv%5B%5D%2C%20char%20**envp%20%29%u51FD%u6570%u3002%0A%0A%20%20%20%20mongo%3A%3AisShell%20%3D%20true%3B%09//%u7528%u6765%u5224%u65AD%u662F%u5426%u542F%u52A8shell%0A%20%20%20%20setupSignals%28%29%3B%09//%u8BBE%u7F6ELinux%u4FE1%u53F7%u5904%u7406%u51FD%u6570%0A%0A%20%20%20%20mongo%3A%3Ashell_utils%3A%3ARecordMyLocation%28%20argv%5B%200%20%5D%20%29%3B%0A%0A%20%20%20%20shellGlobalParams.url%20%3D%20%22test%22%3B//%u9ED8%u8BA4%u8FDE%u63A5%u5230test%u6570%u636E%u5E93%0A%09//%u540Cmongod%uFF0C%u6839%u636E%u547D%u4EE4%u884C%u521D%u59CB%u5316%u5168%u5C40%u53D8%u91CF%0A%09mongo%3A%3ArunGlobalInitializersOrDie%28argc%2C%20argv%2C%20envp%29%3B%0A%09%0A%20%20%20%20//%20hide%20password%20from%20ps%20output%0A%20%20%20%20for%20%28%20int%20i%20%3D%200%3B%20i%20%3C%20%28argc-1%29%3B%20++i%20%29%20%7B%0A%20%20%20%20%20%20%20%20if%20%28%20%21strcmp%28argv%5Bi%5D%2C%20%22-p%22%29%20%7C%7C%20%21strcmp%28%20argv%5Bi%5D%2C%20%22--password%22%20%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20char*%20arg%20%3D%20argv%5Bi%20+%201%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20while%20%28%20*arg%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*arg++%20%3D%20%27x%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20%28%21mongo%3A%3AserverGlobalParams.quiet%29%0A%20%20%20%20%20%20%20%20cout%20%3C%3C%20%22MongoDB%20shell%20version%3A%20%22%20%3C%3C%20mongo%3A%3AversionString%20%3C%3C%20endl%3B%0A%0A%20%20%20%20mongo%3A%3AStartupTest%3A%3ArunTests%28%29%3B%0A%20%20%20%20...%0A%09//%u5982%u679C%u6CA1%u6709%u914D%u7F6Enodb%uFF0C%u5219%u751F%u6210%u8FDE%u63A5%u670D%u52A1%u5668%u7684js%u811A%u672C%uFF0C%u73B0%u5728%u8FD8%u4E0D%u4F1A%u6267%u884C%0A%09//%u5728%u4E4B%u540E%u521D%u59CB%u5316V8%u5F15%u64CE%u540E%u624D%u4F1A%u8FDE%u63A5%u670D%u52A1%u5668%0A%20%20%20%20if%20%28%21shellGlobalParams.nodb%29%20%7B%20//%20connect%20to%20db%0A%20%20%20%20%20%20%20%20stringstream%20ss%3B%0A%20%20%20%20%20%20%20%20if%20%28mongo%3A%3AserverGlobalParams.quiet%29%0A%20%20%20%20%20%20%20%20%20%20%20%20ss%20%3C%3C%20%22__quiet%20%3D%20true%3B%22%3B%0A%20%20%20%20%20%20%20%20ss%20%3C%3C%20%22db%20%3D%20connect%28%20%5C%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20fixHost%28shellGlobalParams.url%2C%20shellGlobalParams.dbhost%2C%20shellGlobalParams.port%29%0A%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20%22%5C%22%29%22%3B%0A%0A%20%20%20%20%20%20%20%20mongo%3A%3Ashell_utils%3A%3A_dbConnect%20%3D%20ss.str%28%29%3B%0A%09%09//%u5982%u679C%u9700%u8981%u8BA4%u8BC1%uFF0C%u5219%u8BA9%u7528%u6237%u8F93%u5165%u5BC6%u7801%0A%20%20%20%20%20%20%20%20if%20%28shellGlobalParams.usingPassword%20%26%26%20shellGlobalParams.password.empty%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20shellGlobalParams.password%20%3D%20mongo%3A%3AaskPassword%28%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%u4E0B%u9762%u90E8%u5206%u4EE3%u7801%u751F%u6210%u4E00%u5806JS%u9A8C%u8BC1%u4FE1%u606F%uFF0C%u540C%u6837%u9A8C%u8BC1%u4E5F%u4F1A%u5728V8%u521D%u59CB%u5316%u4E4B%u540E%u8FDB%u884C%28%u5728mongo%3A%3Ashell_utils%3A%3AinitScope%u51FD%u6570%u4E2D%29%u3002%0A%0A%20%20%20%20stringstream%20authStringStream%3B%0A%20%20%20%20authStringStream%20%3C%3C%20%22%28function%28%29%20%7B%20%22%20%3C%3C%20endl%3B%0A%20%20%20%20if%20%28%21shellGlobalParams.authenticationMechanism.empty%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22DB.prototype._defaultAuthenticationMechanism%20%3D%20%5C%22%22%20%3C%3C%0A%20%20%20%20%20%20%20%20%20%20%20%20escape%28shellGlobalParams.authenticationMechanism%29%20%3C%3C%20%22%5C%22%3B%22%20%3C%3C%20endl%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20%28%21shellGlobalParams.gssapiServiceName.empty%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22DB.prototype._defaultGssapiServiceName%20%3D%20%5C%22%22%20%3C%3C%0A%20%20%20%20%20%20%20%20%20%20%20%20escape%28shellGlobalParams.gssapiServiceName%29%20%3C%3C%20%22%5C%22%3B%22%20%3C%3C%20endl%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20%28%21shellGlobalParams.nodb%20%26%26%20shellGlobalParams.username.size%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22var%20username%20%3D%20%5C%22%22%20%3C%3C%20escape%28shellGlobalParams.username%29%20%3C%3C%20%22%5C%22%3B%22%20%3C%3C%0A%20%20%20%20%20%20%20%20%20%20%20%20endl%3B%0A%20%20%20%20%20%20%20%20if%20%28shellGlobalParams.usingPassword%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22var%20password%20%3D%20%5C%22%22%20%3C%3C%20escape%28shellGlobalParams.password%29%20%3C%3C%20%22%5C%22%3B%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20%28shellGlobalParams.authenticationDatabase.empty%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22var%20authDb%20%3D%20db%3B%22%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22var%20authDb%20%3D%20db.getSiblingDB%28%5C%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20escape%28shellGlobalParams.authenticationDatabase%29%20%3C%3C%20%22%5C%22%29%3B%22%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22authDb._authOrThrow%28%7B%20%22%20%3C%3C%0A%20%20%20%20%20%20%20%20%20%20%20%20saslCommandUserFieldName%20%3C%3C%20%22%3A%20username%20%22%3B%0A%20%20%20%20%20%20%20%20if%20%28shellGlobalParams.usingPassword%29%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22%2C%20%22%20%3C%3C%20saslCommandPasswordFieldName%20%3C%3C%20%22%3A%20password%20%22%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20%28%21shellGlobalParams.gssapiHostName.empty%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22%2C%20%22%20%3C%3C%20saslCommandServiceHostnameFieldName%20%3C%3C%20%22%3A%20%5C%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20escape%28shellGlobalParams.gssapiHostName%29%20%3C%3C%20%27%22%27%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20authStringStream%20%3C%3C%20%22%7D%29%3B%22%20%3C%3C%20endl%3B%0A%20%20%20%20%7D%0A%20%20%20%20authStringStream%20%3C%3C%20%22%7D%28%29%29%22%3B%0A%20%20%20%20mongo%3A%3Ashell_utils%3A%3A_dbAuth%20%3D%20authStringStream.str%28%29%3B%0A%0A%u4E0A%u9762%u90E8%u5206%u4E00%u5982%u65E2%u5F80%u7684%u8FDB%u884C%u5168%u5C40%u53D8%u91CF%u521D%u59CB%u5316%uFF0C%u4E4B%u540E%u4E0B%u9762%u90E8%u5206%u5C06%u4F1A%u521D%u59CB%u5316V8%u5F15%u64CE%0A%0A%09mongo%3A%3AScriptEngine%3A%3AsetConnectCallback%28%20mongo%3A%3Ashell_utils%3A%3AonConnect%20%29%3B%0A%20%20%20%20mongo%3A%3AScriptEngine%3A%3Asetup%28%29%3B%0A%20%20%20%20mongo%3A%3AglobalScriptEngine-%3EsetScopeInitCallback%28%20mongo%3A%3Ashell_utils%3A%3AinitScope%20%29%3B%0A%20%20%20%20auto_ptr%3C%20mongo%3A%3AScope%20%3E%20scope%28%20mongo%3A%3AglobalScriptEngine-%3EnewScope%28%29%20%29%3B%0A%20%20%20%20shellMainScope%20%3D%20scope.get%28%29%3B%0A%0A%u9996%u5148%u521D%u59CB%u5316ScriptEngine%uFF0C%u7136%u540E%u8BBE%u7F6EScope%u521D%u59CB%u5316%u56DE%u8C03%u51FD%u6570initScope%20%uFF0C%u4E4B%u540E%u8C03%u7528newScope%28%29%u51FD%u6570%u8FD4%u56DEV8Scope%u5BF9%u8C61%uFF0C%u540C%u65F6%u8FDE%u63A5%u6570%u636E%u5E93%uFF0C%u6839%u636E%u4E4B%u524D%u751F%u6210%u7684%u4FE1%u606F%u8FDB%u884C%u9A8C%u8BC1%u3002%0A%0AV8%u521D%u59CB%u5316%u4E4B%u540E%u9996%u5148%u4F1A%u53BB%u6267%u884Cmongorc.js%u914D%u7F6E%u6587%u4EF6%uFF0C%u8FD9%u4E2A%u6709%u70B9%u50CFvim%u7684.vimrc%u6587%u4EF6%uFF0C%u6240%u4EE5%u4E00%u4E9B%u5FC5%u987B%u8981%u5148%u6267%u884C%u7684%u4EE3%u7801%u53EF%u4EE5%u5199%u5230mongorc.js%u6587%u4EF6%u4E2D%u3002%0A%0A%20%20%20%20std%3A%3Astring%20rcGlobalLocation%3B%0A%09%23ifndef%20_WIN32%0A%20%20%20%20rcGlobalLocation%20%3D%20%22/etc/mongorc.js%22%20%3B%0A%09%23else%0A%20%20%20%20wchar_t%20programDataPath%5BMAX_PATH%5D%3B%0A%20%20%20%20if%20%28%20S_OK%20%3D%3D%20SHGetFolderPathW%28NULL%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20CSIDL_COMMON_APPDATA%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NULL%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20programDataPath%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20rcGlobalLocation%20%3D%20str%3A%3Astream%28%29%20%3C%3C%20toUtf8String%28programDataPath%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20%22%5C%5CMongoDB%5C%5Cmongorc.js%22%3B%0A%20%20%20%20%7D%0A%09%23endif%20%20%20%0A%20%20%20%20if%20%28%20%21rcGlobalLocation.empty%28%29%20%26%26%20%3A%3Amongo%3A%3Ashell_utils%3A%3AfileExists%28rcGlobalLocation%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20if%20%28%20%21%20scope-%3EexecFile%28%20rcGlobalLocation%20%2C%20false%20%2C%20true%20%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20cout%20%3C%3C%20%22The%20%5C%22%22%20%3C%3C%20rcGlobalLocation%20%3C%3C%20%22%5C%22%20file%20could%20not%20be%20executed%22%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%u4ECE%u4EE3%u7801%u4E2D%u53EF%u4EE5%u770B%u51FAmongorc.js%u6587%u4EF6%u5728Windows%u4E0B%u8DEF%u5F84%u662F%25appdata%25%5C%5CMongoDB%5C%5Cmongorc.js%uFF0C%u5728Linux%u4E0B%u9762%u662F%22/etc/mongorc.js%22%u3002%0A%0A%u4E4B%u540E%u4E00%u6BB5%u4E0D%u662F%u5F88%u91CD%u8981%u7684%u4FE1%u606F%u76F4%u63A5%u7565%u8FC7%uFF0C%u6765%u770B%u6700%u540E%u4E00%u90E8%u5206%uFF0C%u5B8C%u6210%u4E4B%u524D%u7684%u6240%u6709%u914D%u7F6E%u4E4B%u540E%uFF0C%u80AF%u5B9A%u662F%u542F%u52A8shell%uFF0C%u7B49%u5F85%u7528%u6237%u8F93%u5165%uFF0C%u6267%u884C%u547D%u4EE4%u3002%0A%0A%20%20%20%20%20%20%20%20shellHistoryInit%28%29%3B%0A%0A%20%20%20%20%20%20%20%20string%20prompt%3B%0A%20%20%20%20%20%20%20%20int%20promptType%3B%0A%0A%20%20%20%20%20%20%20%20while%20%28%201%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20char%20*%20line%20%3D%20shellReadline%28%20prompt.c_str%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20bool%20wascmd%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20string%20cmd%20%3D%20linePtr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%20cmd.find%28%20%22%20%22%20%29%20%3E%200%20%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cmd%20%3D%20cmd.substr%28%200%20%2C%20cmd.find%28%20%22%20%22%20%29%20%29%3B%0A%09%09%09%09//%u5224%u65AD%u7528%u6237%u8F93%u5165%u662F%u5426%u662F%u547D%u4EE4%uFF0C%u5982%u679C%u662F%u5219%u53BB%u6267%u884C%u547D%u4EE4%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%20cmd.find%28%20%22%5C%22%22%20%29%20%3D%3D%20string%3A%3Anpos%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20scope-%3Eexec%28%20%28string%29%22__iscmd__%20%3D%20shellHelper%5B%5C%22%22%20+%20cmd%20+%20%22%5C%22%5D%3B%22%20%2C%20%22%28shellhelp1%29%22%20%2C%20false%20%2C%20true%20%2C%20true%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%20scope-%3EgetBoolean%28%20%22__iscmd__%22%20%29%20%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20scope-%3Eexec%28%20%28string%29%22shellHelper%28%20%5C%22%22%20+%20cmd%20+%20%22%5C%22%20%2C%20%5C%22%22%20+%20code.substr%28%20cmd.size%28%29%20%29%20+%20%22%5C%22%29%3B%22%20%2C%20%22%28shellhelp2%29%22%20%2C%20false%20%2C%20true%20%2C%20false%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20wascmd%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28%20std%3A%3Aexception%26%20e%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cout%20%3C%3C%20%22error2%3A%22%20%3C%3C%20e.what%28%29%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20wascmd%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%09%09%09//%u5982%u679C%u4E0D%u662F%u547D%u4EE4%u5219%u6267%u884Cjs%u811A%u672C%u3002%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%20%21%20wascmd%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%20scope-%3Eexec%28%20code.c_str%28%29%20%2C%20%22%28shell%29%22%20%2C%20false%20%2C%20true%20%2C%20false%20%29%20%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20scope-%3Eexec%28%20%22shellPrintHelper%28%20__lastres__%20%29%3B%22%20%2C%20%22%28shell2%29%22%20%2C%20true%20%2C%20true%20%2C%20false%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20%28%20std%3A%3Aexception%26%20e%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cout%20%3C%3C%20%22error%3A%22%20%3C%3C%20e.what%28%29%20%3C%3C%20endl%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%09%09%09//%u8BB0%u5F55%u7528%u6237%u8F93%u5165%u5386%u53F2%0A%20%20%20%20%20%20%20%20%20%20%20%20shellHistoryAdd%28%20code.c_str%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20free%28%20line%20%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20shellHistoryDone%28%29%3B%0A%u4E0A%u9762%u7684%u4EE3%u7801%u4E2D%u6211%u5220%u9664%u4E86%u524D%u9762%u90E8%u5206%u7684%u5224%u65AD%u903B%u8F91%uFF0C%u53EA%u4FDD%u7559%u4E86js%u7684%u6267%u884C%u90E8%u5206%u3002%u53EF%u4EE5%u770B%u5230%u6574%u4E2A%u6D41%u7A0B%u7684%u6838%u5FC3%u662Fscope-%3Eexec%28...%29%u51FD%u6570%uFF0Cscope%u5176%u5B9E%u662FV8Scope%u5BF9%u8C61%u3002%0A%0A%u7531%u4E8E%u76EE%u524Djs%u65B9%u9762%u6C34%u5E73%u6709%u9650%uFF0Cmongo%u7684%u542F%u52A8%u5C31%u6682%u65F6%u5206%u6790%u5230%u6B64%uFF0C%u4EE5%u540E%u6709%u7A7A%u518D%u6DF1%u5165%u7814%u7A76%u4E00%u4E0BV8%u5F15%u64CE%u548Cjs%u90E8%u5206%u7684%u4EE3%u7801%u3002