我是golang和编程新手。
我编写了一个小程序,将匹配正则表达式的文件从一个目录移动到另一个目录。
该程序在ubuntu 16.04和Centos 6.8(最终版)上成功运行
在某台Centos机器上(我不知道那台机器的确切版本。我知道它是6.?它低于6.8),我得到:
分段错误(核心转储)
我的研究表明,当操作系统不允许我访问内存时会发生此错误。
有人可以告诉我代码中哪里出错了。如果你看到任何不良行为,也请指出。
package main
import (
"flag"
"fmt"
"log"
"os"
"regexp"
"strings"
)
func main() {
batch := flag.Int("batch", 0, "the amount of files to be processed")
pattern := flag.String("pattern", "", "string pattern to be matched")
dir := flag.Int("dir", 0, "key from strings.Split(pattern, '')")
confirm := flag.String("move", "no", "flags if program should move files")
flag.Parse()
d, err := os.Open(".")
if err != nil {
log.Fatal("Could not open directory. ", err)
}
files, err := d.Readdir(*batch)
if err != nil {
log.Fatal("Could not read directory. ", err)
}
for _, file := range files {
fname := file.Name()
match, err := regexp.Match(*pattern, []byte(fname))
if err != nil {
log.Fatal(err)
}
if match == true {
s := strings.Split(fname, "_")
dest := s[*dir]
switch *confirm {
case "no":
fmt.Printf(" %s matches %s\n Dir name = %s\n -----------------------\n", fname, *pattern, dest)
case "yes":
//all directories are expected to be a number.
//terminate execution if directory doesn't match regex
if match, err := regexp.Match("[0-9]", []byte(dest)); match == false {
log.Fatalf("Expected directory name does not match prepared directory.\n Expected dir name must be a number (regex [0-9]) | Current dir name is: %s\n", dest)
if err != nil {
log.Fatal(err)
}
}
//check if direcotry exists. create it if it doesn't
if _, err := os.Stat(dest); os.IsNotExist(err) {
err = os.Mkdir(dest, 0777)
if err != nil {
log.Fatal("Could not create directory. ", err)
}
}
err = os.Rename(fname, fmt.Sprintf("%s/%s", dest, fname))
if err != nil {
log.Fatal("Could not move file. ", err)
}
fmt.Printf("Moved %s to %s\n", fname, dest)
}
}
}
fmt.Println("Exit")
}
答案 0 :(得分:0)
我的第一个猜测是你过度运行's'数组的界限:
dest := s[*dir]
我添加了一些安全检查(参见[已添加]):
package main
import (
"flag"
"fmt"
"log"
"os"
"regexp"
"strings"
)
func main() {
batch := flag.Int("batch", 0, "the amount of files to be processed")
pattern := flag.String("pattern", "", "string pattern to be matched")
dir := flag.Int("dir", 0, "key from strings.Split(pattern, '')")
confirm := flag.String("move", "no", "flags if program should move files")
flag.Parse()
d, err := os.Open(".")
if err != nil {
log.Fatal("Could not open directory. ", err)
}
defer d.Close() // [Added] probably not needed if a directory but doesn't hurt
files, err := d.Readdir(*batch)
if err != nil {
log.Fatal("Could not read directory. ", err)
}
for _, file := range files {
fname := file.Name()
match, err := regexp.Match(*pattern, []byte(fname))
if err != nil {
log.Fatal(err)
}
if match == true {
s := strings.Split(fname, "_")
// [Added] Sanity check *dir index before using
if *dir >= len(s) {
log.Fatalf("dir is out of range: dir=%d len(s)=%d\n", *dir, len(s))
}
dest := s[*dir]
switch *confirm {
case "no":
fmt.Printf(" %s matches %s\n Dir name = %s\n -----------------------\n", fname, *pattern, dest)
case "yes":
//all directories are expected to be a number.
//terminate execution if directory doesn't match regex
if match, err := regexp.Match("[0-9]", []byte(dest)); match == false {
log.Fatalf("Expected directory name does not match prepared directory.\n Expected dir name must be a number (regex [0-9]) | Current dir name is: %s\n", dest)
if err != nil {
log.Fatal(err)
}
}
//check if direcotry exists. create it if it doesn't
if _, err := os.Stat(dest); os.IsNotExist(err) {
err = os.Mkdir(dest, 0777)
if err != nil {
log.Fatal("Could not create directory. ", err)
}
}
err = os.Rename(fname, fmt.Sprintf("%s/%s", dest, fname))
if err != nil {
log.Fatal("Could not move file. ", err)
}
fmt.Printf("Moved %s to %s\n", fname, dest)
// [Added]: Make sure to handle non 'yes/no' answers
default:
log.Fatalf("confirm is invalid '%s'\n", *confirm)
}
}
}
fmt.Println("Exit")
}
不确定您输入的程序是什么,但我看不到任何其他内容会导致分段错误。