作业4

本文介绍了如何使用Go语言开发Linux命令行工具selpg,详细讲解了程序设计、参数解析、Go语言知识点,包括函数、结构体、参数绑定和异常处理等。通过示例展示了如何处理命令行参数,如-s、-e、-l、-f和-d,并提供了测试案例,包括标准输入、输出重定向和错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 实验要求
​ 使用 golang 开发 开发 Linux 命令行实用程序 中的 selpg

2. 实验步骤
开发Linux命令行实用程序

安装pflag
在终端输入以下命令

   go get github.com/spf13/pflag #install到本地
   go test github.com/spf13/pflag #test
   import flag "github.com/spf13/pflag" #导入,可以继续使用flag



参数处理
输入以下代码,并保存为test.go

package main

import (
    "fmt"

    flag "github.com/spf13/pflag"
)

func main() {
    var s int
    flag.IntVarP(&s, "start", "s", 0, "startPage")
    flag.Parse()
    fmt.Printf("%d\n", s)
}


将终端工作路径切换到当前工作目录下
$ go build test.go
$ ./test
0
$ ./test -s10
10
$ ./test -s20
20
$ ./test --start=30
30

结合终端输出的结果,分析以下test.go代码。
flag.IntVarP定义命令行参数
&s——将命令行参数的值绑定到s变量上
“start”——可以通过- -start=30为参数赋值
“s“——可以通过-s10为参数赋值
最后要通过flag.Parse解析
 

2.1 项目所涉及的Go语言知识点
​ 做这次作业需要使用的Go语言的知识点大概有以下几个方面

​ ① 函数

​ ② 结构体

​ ③ 参数的绑定

​ ④ 异常处理

​ ⑤ 文件读写

​ ⑥ 命令行参数的解析

函数介绍

func getArgs(args *Args) :定义命令行参数
func checkArgs(args *Args): 检查参数的合法性
func getReader(args *Args) *bufio.Reader:获取bufio.Reader对象
func execution(args *Args):执行文件读入写出
func readByL(args *Args, reader *bufio.Reader, writer *bufio.Writer):按行读入,并输出到标准输出
func readByF(args *Args, reader *bufio.Reader, writer *bufio.Writer) :按页读入,并输出到标准输出
func readByLWithD(args *Args, reader *bufio.Reader, writer io.WriteCloser) :按行读入,并由管道输出到"-dXXX"
func readByFWithD(args *Args, reader *bufio.Reader, writer io.WriteCloser) :按页读入,并由管道输出到"-dXXX"

 

2.2 理解selpg
​ selpg 是一个自定义命令行程序,全称select page,即从源(标准输入流或文件)读取指定页数的内容到目的地(标准输出流或给给打印机打印)

2.3 Go使用flag包解释命令行参数
flag包能解析的参数有如下四种形式,使用的时候分三种类型:

类型一
cmd -flag=x // 支持所有类型
cmd -flag x // 只支持非bool类型

类型二
cmd -flag // 只支持bool类型

类型三
cmd abc // 没有flag的参数

2.3.1 类型一
类型一定义参数有两种形式,下方Xxx代表类型

2.3.1.1 类型一定义参数
flag.Xxx()

flag.String(), Bool(), Int() 这种形式返回一个指向该参数的指针

例子

var date = flag.Int("d", 20171107, "help message for date") 

flag.Parse()

(注意: date 是指向 -d 参数值的指针)

​ 若在命令行输入 -d=20121212 -a=20 或者 -d 20121212 -a 20,则我们在程序中即可用 *date 取得 -d 的值20121212

​ 若只输入 -a=20 或者 -a 20,因为缺省标志 -d ,则 *date 取到的是 -d 定义中的默认值 20171107

flag.XxxVar()

flag.StringVar(), BoolVar(), IntVar() 这种形式把参数绑定到一个变量

例子

var age int

flag.IntVar(&age, "a", 18, "help message for age")

flag.Parse()


​ 命令行输入-d=20121212 -a=20 或者-d=20121212 -a 20 ,在程序里 变量age 则获取到 -a 的值 20

​ 若只输入-d=20121212 或者-d=20121212,缺省标志-a, 则 变量age 获取定义中的默认值 18

2.3.1.2 类型一解析参数
​ 注意到上面例子最后都带有一行 flag.Parse()

​ 因为定义好参数后,只有调用方法 flag.Parse() 解析命令行参数到定义的flag,这样我们才能使用上面两个例子的 *date 和 age 取得对应flag的参数值

2.3.2 类型二
cmd -flag //该形式只支持bool类型,对应的值是1, 0, t, f, true, false, TRUE, FALSE, True, False

​ 默认的,如果我们在命令行里提供了-flag,则其对应的值为true,否则为flag.Bool/BoolVar中指定的默认值;如果希望显示设置为false则使用-flag=false。

例子

var exist_f = flag.Bool("f", false, "help message for format")

flag.Parse()


​ 当在命令行输入 -d=123 -f 时,程序里 *exist_f 的值就为 true 了

​ 若命令行只输入 -d=123 时,因为缺省-f,*exist_f 的值为事先定义中默认的 false

2.3.3 类型三
cmd abc //没有flag的参数

​ 1.通过 flag.Args() 获取非flag参数列表

​ 2.通过 flag.Arg(i) 来获取非flag命令行第i个参数,i 从 0 开始

​ 3.通过flag.NArg() 获得非flag参数个数

例子

​ 当命令行敲入 -d 20121212 -a 20 Wang yx ,最后两个值即为不带标志的参数

flag.Parse()

var fullName = flag.Args() // fullName = ['Wang', 'yx']

var firstName = flag.Arg(0) // firstName = Wang

var lastName = flag.Arg(1) // lastName = yx

var num = flag.NArg() // num = 2


2.4 命令行参数设计
selpg -s startPage -e endPage [-l linePerPage | -f ][-d dest] filename

必需标志以及参数:

-s,后面接开始读取的页号 int
-e,后面接结束读取的页号 int
s和e都要大于1,并且s <= e,否则提示错误
可选参数:

-l,后面跟行数 int,代表多少行分为一页,不指定 -l 又缺少 -f 则默认按照72行分一页
-f,该标志无参数,代表按照分页符’\f’ 分页
-d,后面接打印机标号,用于将内容传送给打印机打印 我没有打印机用于测试,所以当使用 -d destination(随便一个字符串作参数)时,就会通过管道把内容发送给 grep命令,并把grep处理结果显示到屏幕
filename,唯一一个无标识参数,代表选择读取的文件名
[] 中内容为可选择性输入的
2.5 读写函数
​ 官网解释:bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。

2.5.1 bufio.NewReader
​ os.Stdlin和打开文件都能得到输入数据流,而bufio.NewReader就是一个对象,该对象带有一个缓冲区,与一个数据流绑定。

通过    

rd := bufio.NewReader(fin)
if psa.page_type == false {
    line_ctr = 0
    page_ctr = 1
    for true {
        line, err2 = rd.ReadString('\n')
        if err2 != nil { /* error or EOF */
            break
        }
        line_ctr++
        if line_ctr > psa.page_len {
            page_ctr++
            line_ctr = 1
        }
        if page_ctr >= psa.start_page && page_ctr <= psa.end_page {
            fmt.Fprintf(fout, "%s", line)
        }
    }
} 

创建一个newreader,是bufio.newReader类型,它绑定了一个文件流,用bufio.NewReader对象的好处是我们可以利用这个对象的函数方法,如

line, err := reader.ReadBytes('\n')


​ 这样就能按行读取缓冲区中的数据。

2.5.2 bufio.Writer
​ 这个对象和bufio.Reader很像,不过它是绑定了一个输出数据流。 可以利用

writer := bufio.NewWriter(os.Stdout)
errW := writer.Write(byte[]("line 1"))


​ 导出到标准输出,同样也可以绑定到文件数据流中

2.6 os/exe
​ exec包执行外部命令。它包装了os.StartProcess函数以便更容易的修正输入和输出,使用管道连接I/O,以及作其它的一些调整。
这个包可以帮助我们在程序中启动子进程并使用管道连接I/0。具体用法是先建立一个子进程的输入管道,启动子进程,从父进程接收标准输出,关闭管道,关闭子进程。

2.6.1 exec.Command(filePath)

cmd_grep := exec.Command("./" + args.printDestination)


​ 创建一个命令对象,参数为子进程路径和子进程参数(可选)

2.6.2 func (c *Cmd) StdinPipe() (io.WriteCloser, error)
它构建了到子进程的输入管道,返回一个io.WriterClose对象,这个对象绑定了一个数据流,该数据流是子进程的数据输入流。所以可以直接调用对象的方法writer.Write([]byte)将数据转化为到子进程的标准输入,如:

_, errW := writer.Write([]byte("line 3"))


2.6.3 func (c *Cmd) Start() error
​ 启动子进程

2.6.4 func (*Cmd) Wait
​ 在命令执行完成后调用,返回所调用命令的执行情况,同时释放资源

3. 代码设计
大体框架是:

​ ① 读取命令行参数

​ ② 打开需要处理的文件

​ ③ 根据用户给定参数进行操作

​ ④ 结束读写

3.1 引入所需要的包

import (
    "fmt"
    "os"
    "bufio"
    "github.com/spf13/pflag"
    "os/exec"
    "io"
)


注:由于这里老师要求要使用Unix标准,所以引入pflag包代替flag,但是两个包的函数在使用上面基本是相同的。

3.2 创立记录数据的结构体

type selpg_args struct {
    start_page  int  //开始页码  
    end_page    int  //结束页码
    in_filename string  // 文件名
    page_len    int    // 每一页的大小
    page_type   bool   // 页类型
    print_dest  string  // 打印地
}


3.3 main 函数

func main() {
    //创建结构体数据
    sa := selpg_args{0, 0, "", 5, false, ""}
    //拿到生成的可执行文件的名字
    progname = os.Args[0]
    //初始化结构体数据
    Parser(&sa)
    //处理参数
    processArgs(len(os.Args), &sa)
    //传递参数,完成对应操作
    processInput(&sa)
}


3.4 Parser函数

func Parser(p *selpg_args) {
    pflag.Usage = usage
    pflag.IntVarP(&p.start_page,"start", "s", 0, "首页")
    pflag.IntVarP(&p.end_page,"end","e", 0, "尾页")
    pflag.IntVarP(&p.page_len,"linenum", "l", 5, "打印的每页行数")
    pflag.BoolVarP(&p.page_type,"printdes","f", false, "是否用换页符换页")
    pflag.StringVarP(&p.print_dest, "othertype","d", "", "打印目的地")
    pflag.Parse()
}


注:这里使用pflag包的函数,完成对命令行数据的操作。

3.5 processArgs函数
​ processArgs函数主要是用于处理输入时候的各种错误,比如起始页码是负数,终止页码小于起始页码等情况,增加程序的健壮性,这里给出部分情况。

func processArgs(psa *selpg_args) {
//处理-s 这种情况
if os.Args[1][0] != '-' || os.Args[1][1] != 's' {
        fmt.Fprintf(os.Stderr, "%s: 1st arg should be -s=start_page\n", progname)
        pflag.Usage()
        os.Exit(2)
}
//处理起始的页码小于1的情况
if psa.start_page < 1  {
    fmt.Fprintf(os.Stderr, "%s: invalid start page %s\n", progname, psa.start_page)
    pflag.Usage()
    os.Exit(3)
}
....
....
//检查要操作的文件是否存在
if pflag.NArg() > 0 {
        psa.in_filename = pflag.Arg(0)
        /* check if file exists */
        file, err := os.Open(psa.in_filename)
        if err != nil {
            fmt.Fprintf(os.Stderr, "%s: input file \"%s\" does not exist\n", progname, psa.in_filename)
            os.Exit(7)
}
        /* check if file is readable */
        file, err = os.OpenFile(psa.in_filename, os.O_RDONLY, 0666)
        if err != nil {
            if os.IsPermission(err) {
                fmt.Fprintf(os.Stderr, "%s: input file \"%s\" exists but cannot be read\n", progname, psa.in_filename)
                os.Exit(8)
            }
        }
        file.Close()
}


3.6 processInput函数
​ processInput函数用来对文件的内容进行处理,根据后缀参数的类型完成操作,这里只给出函数的一部分。

func processInput(psa *selpg_args) {
    fin := os.Stdin
    fout := os.Stdout
    var (
         page_ctr int
         line_ctr int
         err error
         err1 error
         err2 error
         line string
         cmd *exec.Cmd
         stdin io.WriteCloser
    )

4. 程序测试

可使用的 selpg 命令字符串示例:

下面的测试结果是两次的,上面的是test.go文件,下面的是wrong.go文件,对比两次的测试结果,有区别之处做了对比

  1. 1

    $ selpg -s1 -e1 input_file

    该命令将把“input_file”的第 1 页写至标准输出(也就是屏幕),因为这里没有重定向或管道。

[ailsa@localhost spf13]$ ./selpg -s1 -e2 -f test.go
package main

import (
	"fmt"

	flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}


./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
  1. 1

    $ selpg -s1 -e1 < input_file

    该命令与示例 1 所做的工作相同,但在本例中,selpg 读取标准输入,而标准输入已被 shell/内核重定向为来自“input_file”而不是显式命名的文件名参数。输入的第 1 页被写至屏幕。

[ailsa@localhost spf13]$ ./selpg -s1 -e1 < input_file.txt
./selpg: done
  1. 1

    $ other_command | selpg -s10 -e20

    “other_command”的标准输出被 shell/内核重定向至 selpg 的标准输入。将第 10 页到第 20 页写至 selpg 的标准输出(屏幕)。

ls | ./selpg -s1 -e2命令这里的test.go与wrong.go两次的结果不同

[ailsa@localhost spf13]$ ls | ./selpg -s10 -e20
./selpg: start_page (10) greater than total pages (1), no output written
./selpg: done
[root@localhost spf13]# ./selpg -s1 -e1 < input_file.txt
./selpg: done
[root@localhost spf13]#  ls | ./selpg -s1 -e2
error_file.txt
input_file.go
input_file.txt
output_file.txt
pflag
pflag.a
selpg
selpg.c
test
test.go
wrong.go
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
  1. 1

    $ selpg -s10 -e20 input_file >output_file

    selpg 将第 10 页到第 20 页写至标准输出;标准输出被 shell/内核重定向至“output_file”。

[ailsa@localhost spf13]$ ./selpg -s10 -e20 input_file.txt output_file.txt
./selpg: start_page (10) greater than total pages (1), no output written
./selpg: done
  1. 1

    $ selpg -s10 -e20 input_file 2>error_file

    selpg 将第 10 页到第 20 页写至标准输出(屏幕);所有的错误消息被 shell/内核重定向至“error_file”。请注意:在“2”和“>”之间不能有空格;这是 shell 语法的一部分(请参阅“man bash”或“man sh”)。

这里对比了两次的输出,但是test.go时的error忘了截图,按理说应该是空的没有输出,下面的wrong.go文件输出了内容:

./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done

[ailsa@localhost spf13]$ sudo  ./selpg -s1 -e2 input_file.txt 2>error_file.txt
bash: error_file.txt: Permission denied
[ailsa@localhost spf13]$ su
Password: 
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt 2>error_file.txt
[root@localhost spf13]# 
root@localhost spf13]#  ./selpg -s10 -e20 input_file.txt output_file.txt
./selpg: start_page (10) greater than total pages (1), no output written
./selpg: done
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt 2>error_file.txt
[root@localhost spf13]# cat error_file.txt
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done




./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
  1. 1

    $ selpg -s10 -e20 input_file >output_file 2>error_file

    selpg 将第 10 页到第 20 页写至标准输出,标准输出被重定向至“output_file”;selpg 写至标准错误的所有内容都被重定向至“error_file”。当“input_file”很大时可使用这种调用;您不会想坐在那里等着 selpg 完成工作,并且您希望对输出和错误都进行保存。

[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>output_file.txt 2>error_file.txt
[root@localhost spf13]# 
  1. 1

    $ selpg -s10 -e20 input_file >output_file 2>/dev/null

    selpg 将第 10 页到第 20 页写至标准输出,标准输出被重定向至“output_file”;selpg 写至标准错误的所有内容都被重定向至 /dev/null(空设备),这意味着错误消息被丢弃了。设备文件 /dev/null 废弃所有写至它的输出,当从该设备文件读取时,会立即返回 EOF。

[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>output_file.txt 2>/dev/null
[root@localhost spf13]# 
  1. 1

    $ selpg -s10 -e20 input_file >/dev/null

    selpg 将第 10 页到第 20 页写至标准输出,标准输出被丢弃;错误消息在屏幕出现。这可作为测试 selpg 的用途,此时您也许只想(对一些测试情况)检查错误消息,而不想看到正常输出。

[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>/dev/null
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[root@localhost spf13]# 
  1. 1

    $ selpg -s10 -e20 input_file | other_command

    selpg 的标准输出透明地被 shell/内核重定向,成为“other_command”的标准输入,第 10 页到第 20 页被写至该标准输入。“other_command”的示例可以是 lp,它使输出在系统缺省打印机上打印。“other_command”的示例也可以 wc,它会显示选定范围的页中包含的行数、字数和字符数。“other_command”可以是任何其它能从其标准输入读取的命令。错误消息仍在屏幕显示。

[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt | ls
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
error_file.txt  input_file.txt   pflag    selpg    test
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt | cat test.go
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
package main

import (
	"fmt"

	flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}


[root@localhost spf13]# 
  1. 1

    $ selpg -s10 -e20 input_file 2>error_file | other_command

    与上面的示例 9 相似,只有一点不同:错误消息被写至“error_file”。

[root@localhost spf13]# ls
error_file.txt  input_file.txt   pflag    selpg    test
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>error_file.txt | ls
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
error_file.txt  input_file.txt   pflag    selpg    test
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# 

下面的是test.go的测试截图:

 

[ailsa@localhost spf13]$ ls
input_file.go  pflag  pflag.a  selpg  selpg.c  test  test.go
[ailsa@localhost spf13]$ go test pflag
can't load package: package pflag: cannot find package "pflag" in any of:
	/usr/lib/golang/src/pflag (from $GOROOT)
	/home/ailsa/gowork/src/pflag (from $GOPATH)
[ailsa@localhost spf13]$ cp pflag /usr/lib/golang/src/
cp: omitting directory ‘pflag’
[ailsa@localhost spf13]$ cp pflag /usr/lib/golang/src/ -rf
cp: cannot create directory ‘/usr/lib/golang/src/pflag’: Permission denied
[ailsa@localhost spf13]$ sudo cp pflag /usr/lib/golang/src/ -rf
[ailsa@localhost spf13]$ sudo cp pflag /home/ailsa/gowork/src/pflag -rf
[ailsa@localhost spf13]$ selpg
bash: selpg: command not found...
[ailsa@localhost spf13]$ ./selpg
./selpg: not enough arguments

USAGE: ./selpg -sstart_page -eend_page [ -f | -llines_per_page ] [ -ddest ] [ in_filename ]
[ailsa@localhost spf13]$ ./selpg -s 1 -e 10 -f
./selpg: invalid start page 

USAGE: ./selpg -sstart_page -eend_page [ -f | -llines_per_page ] [ -ddest ] [ in_filename ]
[ailsa@localhost spf13]$ ls
input_file.go  pflag  pflag.a  selpg  selpg.c  test  test.go
[ailsa@localhost spf13]$ ./selpg -s 1 -e 10 -f test.go
./selpg: invalid start page 

USAGE: ./selpg -sstart_page -eend_page [ -f | -llines_per_page ] [ -ddest ] [ in_filename ]
[ailsa@localhost spf13]$ ./selpg 1 2
./selpg: 1st arg should be -sstart_page

USAGE: ./selpg -sstart_page -eend_page [ -f | -llines_per_page ] [ -ddest ] [ in_filename ]
[ailsa@localhost spf13]$ ./selpg -s 1 -e  2 -f test.go
./selpg: invalid start page 

USAGE: ./selpg -sstart_page -eend_page [ -f | -llines_per_page ] [ -ddest ] [ in_filename ]
[ailsa@localhost spf13]$ ./selpg -s1 -e2 -f test.go
package main

import (
	"fmt"

	flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}


./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[ailsa@localhost spf13]$ 

下面的是wrong.go的测试截图:


import (
	//"fmt"

	//flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}


[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>error_file.txt | ls
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
error_file.txt  input_file.txt   pflag    selpg    test     wrong.go
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# ls
error_file.txt  input_file.txt   pflag    selpg    test     wrong.go
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# cat error_file.txt
[root@localhost spf13]#  ./selpg -s1 -e2 -f wrong.go
package main

import (
	//"fmt"

	//flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}


./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[root@localhost spf13]# clear

[root@localhost spf13]#  ./selpg -s1 -e2 -f wrong.go
package main

import (
	//"fmt"

	//flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}


./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[root@localhost spf13]# ./selpg -s1 -e1 < input_file.txt
./selpg: done
[root@localhost spf13]#  ls | ./selpg -s1 -e2
error_file.txt
input_file.go
input_file.txt
output_file.txt
pflag
pflag.a
selpg
selpg.c
test
test.go
wrong.go
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[root@localhost spf13]#  ./selpg -s10 -e20 input_file.txt output_file.txt
./selpg: start_page (10) greater than total pages (1), no output written
./selpg: done
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt 2>error_file.txt
[root@localhost spf13]# cat error_file.txt
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[root@localhost spf13]# gedit error_file.txt

(gedit:31849): GLib-GIO-CRITICAL **: 22:41:51.010: g_dbus_proxy_new_sync: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

(gedit:31849): dconf-WARNING **: 22:41:51.018: failed to commit changes to dconf: The connection is closed

(gedit:31849): dconf-WARNING **: 22:41:51.025: failed to commit changes to dconf: The connection is closed
Error creating proxy: The connection is closed (g-io-error-quark, 18)
Error creating proxy: The connection is closed (g-io-error-quark, 18)
Error creating proxy: The connection is closed (g-io-error-quark, 18)
Error creating proxy: The connection is closed (g-io-error-quark, 18)
Error creating proxy: The connection is closed (g-io-error-quark, 18)

(gedit:31849): dconf-WARNING **: 22:41:51.206: failed to commit changes to dconf: The connection is closed

(gedit:31849): dconf-WARNING **: 22:41:51.206: failed to commit changes to dconf: The connection is closed

(gedit:31849): dconf-WARNING **: 22:41:51.207: failed to commit changes to dconf: The connection is closed

(gedit:31849): dconf-WARNING **: 22:42:17.454: failed to commit changes to dconf: The connection is closed

** (gedit:31849): WARNING **: 22:42:17.543: Set document metadata failed: Setting attribute metadata::gedit-position not supported
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt 2>error_file.txt./selpg -s1 -e2 input_file.txt>output_file.txt 2>error_file.txt
bash: error_file.txt./selpg: No such file or directory
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>output_file.txt 2>error_file.txt
[root@localhost spf13]# ls
error_file.txt  input_file.txt   pflag    selpg    test     wrong.go
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>output_file.txt 2>error_file.txt
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>output_file.txt 2>/dev/null
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt>/dev/null
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt | ls
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
error_file.txt  input_file.txt   pflag    selpg    test     wrong.go
input_file.go   output_file.txt  pflag.a  selpg.c  test.go
[root@localhost spf13]# ./selpg -s1 -e2 input_file.txt | cat wrong.go
./selpg: end_page (2) greater than total pages (1), less output than expected
./selpg: done
package main

import (
	//"fmt"

	//flag "github.com/spf13/pflag"
)

func main() {
	var s int
	flag.IntVarP(&s, "start", "s", 0, "startPage")
	flag.Parse()
	fmt.Printf("%d\n", s)
}

 

遇到的问题

5 遇到的问题

最大的问题是selpg安装不上去,虚拟机老是死机,pflag获取不到,花了很长时间,配置路径,下载了selpg.c 然后gcc selpg.c -o selpg生成了可执行文件,直接在github上下载压缩解压copy到安装路径和缺包的两个bin目录下selpg终于能使用了,只是不是和文档里面一样的用法,是用了./selpg 。然后就是最开始读文档一头雾水,所以看了很多博客,好像大家都没有遇到我这样的问题,上次配置golang环境也是这样,修改路径还是找不到包最后也是手动copy到bin下面才能用的,这次吃一堑长一智,下次不能再花时间在这个问题上了。虚拟机奔溃的原因暂时还找不到,一打开命令窗口和谷歌浏览器就死机,只能强制关机重启虚拟机,反复好几次简直奔溃,所以又捣鼓了好久主机,考虑如果下次再死机就重装系统试一下了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值