2)当要处理的文件的父路径中没有参数或变量定义的路径时,日志如下:
3)当上传时,在hdfs上无法创建路径,或者无法修改权限时,日志如下:
4) 当文件大小对比失败,或hdfs dfs -put命令执行失败时,日志如下:
5) 脚本中定义了其它相关报错日志,但由于笔者测试过程未出现相关报错,也无法一一列出脚本#!/bin/bash
[ -x /bin/basename ] && bn_cmd=/bin/basename
[ -x /usr/bin/basename ] && bn_cmd=/usr/bin/basename
[ -x /usr/bin/dirname ] && dn_cmd=/usr/bin/dirname
[ -x /usr/bin/wc ] && wc_cmd=/usr/bin/wc
[ -x /usr/bin/uniq ] && uq_cmd=/usr/bin/uniq
[ -x /usr/bin/hdfs ] && hdp_cmd="/usr/bin/hdfs dfs"
# 检查是否有本脚本pid
pid_file=/tmp/`$bn_cmd $0`_ftp_op.pid
if [[ -f $pid_file ]];then
ps -p `cat $pid_file` &> /dev/null
[[ "$?" -eq "0" ]] && echo "`$log_date` : $0 exist." && exit 0
fi
echo $$ > $pid_file
log_date="/bin/date +%H:%M:%S/%Y-%m-%d"
log_dir=/var/log/ftp_op
log_file=$log_dir/ftp_op.log
threads=${1:-10}
thread_script=${2:-/opt/upload_thread.sh}
#check_period=${5:-10}
check_period=5
timestamp="/bin/date +%s"
thread_file_pre=$log_dir/threadfile
max_threads=32
# 5242880 = 5M/s
network_speed=5242880
net_speed=`echo $network_speed $threads|awk '{printf("%.0lf",$1/$2)}'`
if [[ ! -d $log_dir ]];then
mkdir -p $log_dir ; mkdir_res=$?
[[ $mkdir_res -ne 0 ]] && echo "$log_dir : Can't create directory" && exit 1
fi
put_invalid_list=$log_dir/put_hdfs_invalid.list
put_hdfs_list=$log_dir/put_hdfs.list
put_retry_list=$log_dir/retry_put.list
final_dir=${3:-/storage/disk9/localfiles}
hdfs_dir=${4:-/tmp/hdfs/files}
# 日志记录函数
TEE(){
/usr/bin/tee -a $log_file
}
# 重试列表追加入当前列表
# 如果检测到重试列表不为空,追加进上传列表
# 此函需要两个参数 $1 $2
# $1 : 重试列表文件
# $2 : 标准处理列表
RETRY_LIST(){
if [ -f $1 ];then
retry_sum=`cat $1|/usr/bin/wc -l`
if [[ $retry_sum -ne 0 ]];then
cat $1 >> $2
rm -rf $1
fi
fi
}
# 线程个数策略,此函数需要提供两个参数
# $1 : 原始上传列表文件
# $2 : 用户提供的线程个数
THREAD_POLICY(){
if [[ $# -ne 2 ]];then
echo "`$log_date` $FUNCNAME Error: \$# 1= 2" >> $log_file
return 1
fi
if [[ ! -f $1 ]];then
echo "`$log_date` $FUNCNAME $1 No such file" >> $log_file
return 2
fi
echo "$2"|grep -q '^[-]\?[0-9]\+$'
if [[ $? -ne 0 ]];then
echo "`$log_date` $FUNCNAME $2 Invalid number" >> $log_file
return 3
fi
local list_sum=`cat $1|$wc_cmd -l`
if [[ $list_sum -eq 0 ]];then
#echo "`$log_date` $FUNCNAME $1 is empty" >> $log_file
return 0
else
if [[ $2 -ge $max_threads ]];then
[[ "$list_sum" -le "$max_threads" ]] && echo $list_sum || echo $max_threads
else
[[ "$list_sum" -le "$2" ]] && echo $list_sum || echo $2
fi
fi
}
# 超时失败处理,此函数需要提供一个参数
# $1 : 超时线程的pid标识文件
TIMEOUT_HANDLE(){
if [[ ! -f $1 ]];then
echo "`$log_date` $FUNCNAME $1 no such file" >> $log_file
return 1
fi
local old_pid=`/usr/bin/tail -1 $1`
ps -p $old_pid &> /dev/null
if [[ $? -eq 0 ]];then
kill $old_pid &> /dev/null
if [[ $? -eq 0 ]];then
sed -n "1p" $1 >> $put_retry_list
rm -rf $1
return 0
else
echo "`$log_date` $FUNCNAME $2 kill $old_pid fail." >> $log_file
local file_dir=`$dn_cmd $1` ; local file_name=`$bn_cmd $1`
sed -n "1p" $1 >> $put_retry_list
mv -f $1 $file_dir/fail_kill_$file_name
ps -p $old_pid &> /dev/null
if [[ $? -eq 0 ]];then
echo "`$log_date` $FUNCNAME $2 kill $old_pid fail." >> $log_file
return 1
else
return 0
fi
fi
else
sed -n "1p" $1 >> $put_retry_list
rm -rf $1
fi
# $put_hdfs_list $put_retry_list $threads
}
# 创建线程执行脚本所需文件,此函数需要两个参数
# $1 : 线程执行脚本id号
# $2 : 要处理的具体文件的绝对路径
CREATE_THREAD_FILE(){
if [[ $# -ne 2 ]];then
echo "`$log_date` $FUNCNAME Error \$#!=2" >> $log_file
return 1
fi
if [[ -z $1 ]];then
echo "`$log_date` $FUNCNAME $1 is empty" >> $log_file
return 0
fi
if [[ ! -f $2 ]];then
echo "`$log_date` $FUNCNAME $2 no such file" >> $log_file
return 2
fi
local file_size=`/usr/bin/du -b $2|awk '{print $1}'`
local time_out=`echo $file_size $net_speed|awk '{printf("%.0lf",$1/$2+60)}'`
local thread_file="$thread_file_pre"_"$1"_`$timestamp`_"$file_size"_"$time_out"
echo $2 > $thread_file
if [[ $? -eq 0 ]];then
echo $thread_file
return 0
else
echo "`$log_date` $FUNCNAME $thread_file Can't create file" >> $log_file
return 3
fi
}
# 超时策略,此函数需要提供两个参数
# $1 : 当前需要创建的线程个数id
# $2 : 要处理文件的绝对路径
THREAD_FILE_POLICY(){
if [[ $# -ne 2 ]];then
echo "`$log_date` $FUNCNAME Error \$#!=2" >> $log_file
return 1
fi
if [[ -z $1 ]];then
echo "`$log_date` $FUNCNAME $1 is empty" >> $log_file
return 0
fi
if [[ ! -f $2 ]];then
echo "`$log_date` $FUNCNAME $2 no such file" >> $log_file
return 2
fi
local old_file=`/bin/ls "$thread_file_pre"_"$1"_* 2> /dev/null`
if [[ -f $old_file ]];then
local now_time=`$timestamp`
local old_time=`$bn_cmd $old_file|awk -F_ '{print $3}'`
local file_timeout=`$bn_cmd $old_file|awk -F_ '{print $NF}'`
local now_timeout=`echo $now_time $old_time|awk '{printf("%.0lf",$1-$2)}'`
if [[ $now_timeout -le $file_timeout ]];then
return 0
else
if TIMEOUT_HANDLE $old_file ;then
echo `CREATE_THREAD_FILE $1 $2`
fi
fi
else
echo `CREATE_THREAD_FILE $1 $2`
fi
}
# 主控进程函数
MASTER_CTRL(){
if [[ $# -ne 4 ]];then
echo "`$log_date` $FUNCNAME Error \$#!=4" >> $log_file
return 1
fi
while :;do
RETRY_LIST $2 $1
local final_threads=`THREAD_POLICY $1 $4`
[[ -z $final_threads ]] && break
for t in `/usr/bin/seq 1 $final_threads`;do
local file_path=`sed -n "1p" $1`
echo $file_path|grep -q $final_dir
if [[ $? -ne 0 ]];then
echo "`$log_date` $FUNCNAME $file_path invalid file" >> $log_file
echo $file_path >> $put_invalid_list
sed -i "1d" $1
continue
fi
local thread_file=`THREAD_FILE_POLICY $t $file_path`
if [[ -f $thread_file ]];then
/bin/bash $3 $thread_file $final_dir $hdfs_dir $2 &
sed -i "1d" $1
fi
done
[[ ! -z $final_threads ]] && sleep $check_period
done
rm -rf $pid_file
}
MASTER_CTRL $put_hdfs_list $put_retry_list $thread_script $threads#!/bin/bash
[[ ! -f $1 ]] && echo "Error, Invalid File" && exit 1
[[ ! -d $2 ]] && echo "Error, Invalid Directory" && exit 1
echo $$ >> $1
[ -x /bin/basename ] && bn_cmd=/bin/basename
[ -x /usr/bin/basename ] && bn_cmd=/usr/bin/basename
[ -x /usr/bin/dirname ] && dn_cmd=/usr/bin/dirname
[ -x /usr/bin/wc ] && wc_cmd=/usr/bin/wc
[ -x /usr/bin/uniq ] && uq_cmd=/usr/bin/uniq
[ -x /usr/bin/hdfs ] && hdp_cmd="/usr/bin/hdfs dfs"
[ -x /usr/bin/md5sum ] && ms_cmd=/usr/bin/md5sum
log_date="/bin/date +%H:%M:%S/%Y-%m-%d"
log_dir=/var/log/ftp_op
log_file=$log_dir/ftp_op.log
put_retry_list=${5:-$log_dir/retry_put.list}
timestamp="/bin/date +%s"
now_timestamp=`$timestamp`
[ ! -d $log_dir ] && mkdir -p $log_dir
# 日志记录函数
TEE(){
/usr/bin/tee -a $log_file
}
# 本地和hdfs的文件大小对比函数
# 此函数需要两个参数 $1 $2
# $1为本地文件大小 $2为hdfs文件路径
HDFS_SIZE_CHECK(){
if [[ $# -ne 2 ]];then
echo "`$log_date` $FUNCNAME Error \$#!=2 \$1 or \$2 is empty"|TEE
return 1
fi
local hdfs_size=`$hdp_cmd -du $2|awk '{print $1}'`
[[ $1 -eq $hdfs_size ]] && return 0 || return 1
}
# 此函数需要三个参数
# $1 : hdfs的文件名
# $2 : 本地的对应文件的大小
# $3 : hdfs文件的目录
HDFS_LOCATION_CHECK(){
if [[ $# -ne 3 ]];then
return 2
fi
if $hdp_cmd -test -d $3 ;then
if $hdp_cmd -test -f $1 ;then
if HDFS_SIZE_CHECK $2 $1 ;then
$hdp_cmd -rm -r -f -skipTrash $1.tmp
return 1
else
$hdp_cmd -rm -r -f -skipTrash $1
fi
fi
if $hdp_cmd -test -f $1.tmp ;then
if HDFS_SIZE_CHECK $2 $1.tmp ;then
$hdp_cmd -mv $1.tmp $1
return 1
else
$hdp_cmd -rm -r -f -skipTrash $1.tmp
return 0
fi
else
return 0
fi
else
if $hdp_cmd -mkdir -p $3 ;then
$hdp_cmd -chmod 777 $3 && return 0 || return 4
else
return 3
fi
fi
}
# 此函数仅作上传处理,此函数需要五个参数
# $1 需要上传的本地文件
# $2 要上传到hdfs的目标文件
# $3 本地文件的大小byte
# $4 分配的超时时间
# $5 本地文件的du -sh的统计大小
ONLY_UPLOAD(){
if [[ $# -ne 5 ]];then
echo "`$log_date` $FUNCNAME Error: \$# != 5"|TEE
return 1
fi
if [[ ! -f $1 ]];then
echo "`$log_date` $FUNCNAME Error: \$1=$1 no such file"|TEE
return 1
fi
$hdp_cmd -put -f $1 $2.tmp &> /dev/null
if HDFS_SIZE_CHECK $3 $2.tmp ;then
$hdp_cmd -mv $2.tmp $2 &> /dev/null
local nowtime=`$timestamp` ; local costtime=`/usr/bin/expr $nowtime - $now_timestamp`
echo "`$log_date` $FUNCNAME $2 Upload Success $5 $costtime $4" >> $log_file
return 0
else
$hdp_cmd -rm -r -f -skipTrash $2.tmp &> /dev/null
return 1
fi
}
# 上传HDFS
PUT_TO_HDFS(){
if [[ $# -ne 3 ]];then
echo "`$log_date` $FUNCNAME Error: \$# 1= 3"|TEE
return 1
elif [[ ! -f $1 ]];then
echo "`$log_date` $FUNCNAME Error: \$1 Invalid File"|TEE
return 1
elif [[ ! -d $2 ]];then
echo "`$log_date` $FUNCNAME Error: \$2 Invalid Directory"|TEE
return 1
elif [[ -z $3 ]];then
echo "`$log_date` $FUNCNAME Error: \$3 is Empty"|TEE
return 1
fi
local list_sum=`cat $1|$wc_cmd -l`
if [[ $list_sum -ne 2 ]];then
echo "`$log_date` $FUNCNAME $1 is invalid pidfile"|TEE
return 2
fi
local local_file=`sed -n "1p" $1`
local local_size=`$bn_cmd $1|awk -F_ '{print $4}'`
local hdfs_file=`echo $local_file|sed "s@$2@$3@1"`
local hdfs_dir=`/usr/bin/dirname $hdfs_file`
local valid_time=`$bn_cmd $1|awk -F_ '{print $NF}'`
local filesize=`/usr/bin/du -sh $local_file|awk '{print $1}'`
HDFS_LOCATION_CHECK $hdfs_file $local_size $hdfs_dir ; hlc_rev=$?
local nowtime=`$timestamp`
local costtime=`/usr/bin/expr $nowtime - $now_timestamp`
case $hlc_rev in
0)
ONLY_UPLOAD $local_file $hdfs_file $local_size $valid_time $filesize
if [[ $? -ne 0 ]] ;then
sed -n "1p" $1 >> $put_retry_list
local nowtime=`$timestamp` ; local costtime=`/usr/bin/expr $nowtime - $now_timestamp`
echo "`$log_date` ONLY_UPLOAD Upload Failed $filesize $costtime $valid_time" >> $log_file
fi
;;
1)
echo "`$log_date` $FUNCNAME $hdfs_file Upload Success $filesize $costtime $valid_time (check size)" >> $log_file ;;
2)
sed -n "1p" $1 >> $put_retry_list
echo "`$log_date` HDFS_LOCATION_CHECK Upload Failed: \$# != 2 $filesize $costtime $valid_time" >> $log_file ;;
3)
sed -n "1p" $1 >> $put_retry_list
echo "`$log_date` HDFS_LOCATION_CHECK Upload Failed: Can't create directory -> $hdfs_dir $filesize $costtime $valid_time" >> $log_file ;;
4)
sed -n "1p" $1 >> $put_retry_list
echo "`$log_date` HDFS_LOCATION_CHECK Upload Failed: Can't chmod 777 $hdfs_dir on the hdfs $filesize $costtime $valid_time" >> $log_file ;;
esac
rm -rf $1
}
PUT_TO_HDFS $1 $2 $3我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题