http://hi.baidu.com/zxhathust/blog/item/cc94e3fb2736ba62024f5619.html/cmtid/e34f1b1ccfa1648286d6b622
Matlab R2007a 中存在保存路径的 Bug,症状如下:
当你修改了(增加或删除)搜索路径,并 savepath 后。以后每次启动 MATLAB ,会在 Command Window 的第一行显示下面信息:
Warning: Duplicate directory name: C:\Documents and Settings\c_c\My Documents\MATLAB.
而我们 File --> Set Path,进入路径设置对话框,在“MATLAB search path:”栏里可以看到只有一个上面提示中的目录,而并没有重复的目录。但却每次都提示这个 Warning,至少这会让你感觉很不爽。
一、Bug出处
事实上,造成上面的原因并不是真的多了一个提示中的目录,而是我们修改路径后
保存设置时出了问题(命令savepath存在bug!),问题就出在这个savepath.m文件上。
我们在 Matlab 的官网上也可以看到这个 bug 信息,如下:
如上所述,这个bug 存在于 Matlab R2007a 上,到了版本 R2007b 已经得到解决。
二、解决办法
官网上同时也给出了问题的解决办法,如下:
Exit MATLAB.
Download the attached savepath.m file to replace the existing savepath.m at
matlabroot\toolbox\matlab\general\savepath.m
where matlabroot is the directory in which MATLAB is installed, which you can determine by running the matlabroot function in MATLAB.
Start MATLAB from the Windows desktop shortcut or from Windows Start > Programs.
Run savepath in the Command Window.
The warning should no longer appear.
如上所述,按以下步骤可解决此 bug :
1)下载修正后的 savepath.m 文件 (点击此处下载savepath.m )
2)如果你正在运行 Matlab,退出 Matlab
3)假如你的 Matlab 安装在目录 D:\Program Files\MATLAB 下,则进入目录
D:\Program Files\MATLAB\R2007a\toolbox\matlab\general 找到并删除这里的 savepath.m 文件,
4)将(1)步中下载的 savepath.m 文件 拷到此目录。
5)启动 Matlab,在 Command Window 输入 savepath 命令即可解决此问题
6)再次重起 Matlab,那个讨厌的 Warning 即会消失
其实不用到其网站下载,savepath.m 文件内容为(在那个文件夹下把下面的内容替换原先程序里面的内容就可以了):
function notsaved = savepath(outputfile)
%SAVEPATH Save the current MATLAB path in the pathdef.m file.
% SAVEPATH saves the current MATLABPATH in the pathdef.m
% which was read on startup.
%
% SAVEPATH outputFile saves the current MATLABPATH in the
% specified file.
%
% SAVEPATH returns:
% 0 if the file was saved successfully
% 1 if the file could not be saved
%
% See also PATHDEF, ADDPATH, RMPATH, PATH, PATHTOOL.
% Copyright 1984-2006 The MathWorks, Inc.
% $Revision: 1.1.4.12.2.1 $ $Date: 2007/02/28 22:06:17 $
% Assume that things are going well until we learn otherwise.
result = 0;
% Unless the user specifies otherwise, we're going to overwrite the
% pathdef.m file that MATLAB currently sees.
if nargin == 0
outputfile = which('pathdef.m');
else
if ~ischar(outputfile)
if nargout == 1
notsaved = 1;
end
return;
end
end
% This is a token string that we will look for in the template file.
magic_string = 'PLEASE FILL IN ONE DIRECTORY PER LINE';
templatefile = fullfile(matlabroot, 'toolbox', 'local', 'template', 'pathdef.m');
% Try to read the template file. If we can't, that's OK, we have a
% backup plan.
fid = fopen(templatefile, 'r');
if fid ~= -1
template = fread(fid,'*char')';
fclose(fid);
else
template = ['function p = pathdef', 10, ...
'%PATHDEF Search path defaults.', 10, ...
'% PATHDEF returns a string that can be used as input to MATLABPATH', 10, ...
'% in order to set the path.', 10, 10, ...
'% DO NOT MODIFY THIS FILE. IT IS AN AUTOGENERATED FILE.', 10, ...
'% EDITING MAY CAUSE THE FILE TO BECOME UNREADABLE TO', 10, ...
'% THE PATHTOOL AND THE INSTALLER.', 10, 10, ...
'p = [...', 10, ...
'%%% BEGIN ENTRIES %%%', 10, ...
magic_string, 10, ...
'%%% END ENTRIES %%%', 10, ...
' ...', 10, ...
'];', 10, 10, ...
'p = [userpath,p];', 10];
end
% Find the location of the "magic string" in the file.
magic_index = findstr(template, magic_string);
% Take everything that appears *before* the "magic string" line as
% "firstpart," and everything that appears after that line as
% "lastpart."
% We'll sandwich the path particulars between the two ends.
firstpart = template(1:magic_index-1);
lastpart = template(magic_index + 1:end);
lfs_in_firstpart = find(firstpart == 10, 1, 'last');
firstpart = firstpart(1:lfs_in_firstpart);
lfs_in_lastpart = find(lastpart == 10, 1, 'first');
lastpart = lastpart(lfs_in_lastpart+1:end);
% Read the current path.
thepath = matlabpath;
% First, Break the path down into a cell array of strings, one for
% each entry in the path. We leave the pathsep on the end of each
% string. The path might not actually *end* with a pathsep, but if
% not, we add one for consistency's sake.
ps = pathsep;
if thepath(end) ~= ps
thepath = [thepath ps];
end
% Get the exact form of the entries that we want to create in the
% new pathdef file based on the path. all_path_lines will be a
% cell array of strings.
all_path_lines_matches = regexp(thepath,['(.[^' ps ']*' ps '?)'],'tokens');
all_path_lines = [all_path_lines_matches{:}]';
% g363196 - For the PC Windows, exclude the value of $documents\MATLAB
% from being saved because it is dynamic (per user) and
% automatically placed on the path by userpath.m on startup.
cname = computer;
if (strncmp(cname,'PC',2))
try
% What is the current $documents\MATLAB ?
[rc sd] = dos('startdir $documents\MATLAB -a');
sd = strcat(sd,';');
% Exclude it from path list that will be saved
% Use the indices returned by setdiff to reconstruct the
% resulting set while preserving the order
[unused indices] = setdiff(all_path_lines,sd);
all_path_lines = all_path_lines(sort(indices));
catch
end
end
all_path_lines = matlabrootify(all_path_lines);
% Start constructing the contents of the new file. We start with
% the firstpart.
cont = firstpart;
% Append the paths separated by newline characters
cont = [cont all_path_lines{:}];
% Conclude with the lastpart.
cont = [cont lastpart];
% We have the completed new text of the file, so we try to write it out.
% Return immediately if a directory.
if isdir(outputfile)
if nargout == 1
notsaved = 1;
end
return;
end
fid = fopen(outputfile, 'w');
if fid == -1
% We failed to open the file for writing. That might be
% because we don't have write permission for that file. Let's
% try to make it read-write.
if isunix
unix(['\chmod 666 ''', outputfile, '''']);
elseif ispc && ~strncmpi('\\', pwd, 2)
dos(['attrib -r "', outputfile, '"']);
end
% Last chance. Can we write to it? If we fail here, we have
% no choice but to fail.
fid = fopen(outputfile, 'w');
if fid == -1
result = 1;
if nargout == 1
notsaved = result;
end
return;
end
end
% Write it out.
count = fprintf(fid,'%s', cont);
if count < length(template)
result = 1;
end
fclose(fid);
clear pathdef; %make sure that pathdef gets cleared.
if nargout == 1
notsaved = result;
end
%---------------------------------------------
function dirnames = matlabrootify(dirnamesIn)
% Given a cell array of path entries, this performs two functions:
% (1) If the path entry under consideration is a subdirectory of
% matlabroot, it encodes that information directly into the string.
% Therefore, even if the location of the MATLAB installation is changed,
% pathdef.m will still point to the appropriate location.
% (2) Performs additional formatting.
% If we're on PC, we want to do our comparisons in a case-insensitive
% fashion. Since it also doesn't matter what case the entries are made in,
% we might as well lowercase everything now - no harm done.
if ispc
mlroot = lower(matlabroot);
dirnames = lower(dirnamesIn);
else
mlroot = matlabroot;
dirnames = dirnamesIn;
end
% Find indices to entries in the MATLAB root. One match must be at the
% start of the entry. Calculate indices to remaining entries, and preserve
% case-sensitivity
mlr_dirs = cellfun(@(x) ismember(1,x),strfind(dirnames,mlroot));
dirnames(~mlr_dirs) = dirnamesIn(~mlr_dirs);
% We'll need to wrap all the entries in strings, so do some quote escaping
dirnames = strrep(dirnames, '''', '''''');
% Replace MATLAB roots with "matlabroot" only at the start of the entry,
% and wrap entires in quotes. Be sure to escape backslash in mlroot since it
% is a metacharacter to regexprep.
dirnames(mlr_dirs) = regexprep(dirnames(mlr_dirs),strrep(mlroot,'\','\\'),' matlabroot,''','once');
dirnames(~mlr_dirs) = strcat(' ''',dirnames(~mlr_dirs));
dirnames = strcat(dirnames, ''', ...', {char(10)});