AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 493657
Accepted
hawkeye
hawkeye
Asked: 2019-01-11 02:23:49 +0800 CST2019-01-11 02:23:49 +0800 CST 2019-01-11 02:23:49 +0800 CST

Como excluir todos os diretórios em um diretório com mais de 2 semanas, exceto o mais recente que corresponde a um padrão de arquivo?

  • 772

Tenho o seguinte caminho:

/dir1/dir2/

Neste caminho, tenho os seguintes diretórios contendo vários detrius de aplicativos (não relevantes):

follower1234  1-Dec-2018
follower3456  2-Dec-2018
follower4567  3-Dec-2018
follower7890  9-Jan-2019
follower8901 10-Jan-2019
leader8765    4-Dec-2018
bystander6789 5-Dec-2018

Suponha que hoje seja 10 de janeiro de 2019.

Suponha que pode haver qualquer número de followerXXXXdiretórios leaderXXXXe bystanderXXXX.

O que eu quero é excluir todos os followerXXXXdiretórios, exceto o followerXXXdiretório mais recente, que tem mais de duas semanas.

Agora posso excluir todos os diretórios anteriores a uma determinada data . Mas essa não é a minha pergunta. Estou adicionando dois parâmetros adicionais.

Neste caso eu quero deletar:

follower1234  1-Dec-2018
follower3456  2-Dec-2018
follower4567  3-Dec-2018

Mas não

follower7890  9-Jan-2019
follower8901 10-Jan-2019
leader8765    4-Dec-2018
bystander6789 5-Dec-2018

ou seja, eu quero excluir arquivos

(a) correspondendo a um padrão

(b) mais de duas semanas

(c) não é o diretório mais recente que corresponde ao padrão (ou seja, mantenha o último)

Minha pergunta é: Como excluir todos os diretórios em um diretório com mais de 2 semanas, exceto o mais recente que corresponde a um padrão de arquivo?

shell-script directory
  • 5 5 respostas
  • 7527 Views

5 respostas

  • Voted
  1. Best Answer
    sudodus
    2019-01-11T05:03:30+08:002019-01-11T05:03:30+08:00

    Introdução

    A pergunta foi modificada.

    • Minha primeira alternativa (o oneliner) não corresponde à nova especificação, mas salva o diretório mais recente entre os diretórios antigos o suficiente para serem excluídos (mais de 14 dias).

    • Eu fiz uma segunda alternativa, (o shellscript) que usa

      @ segundos desde 1º de janeiro de 1970, 00:00 GMT, com parte fracionária.

      e subtraindo os segundos correspondentes a 14 dias para obter um timestamp para o 'limit-in-seconds' na seclimlista ordenada de diretórios.

    1. Oneliner

    As respostas anteriores são limpas e agradáveis, mas não preservam o followerdiretório mais recente. A seguinte linha de comando fará isso (e pode gerenciar nomes com espaços, mas nomes com novas linhas criam problemas),

    find . -type d -name "follower*" -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs echo rm -r
    

    testado nesta estrutura de diretórios,

    $ find -printf "%T+ %p\n"|sort
    2019-01-10+13:11:40.6279621810 ./follower1
    2019-01-10+13:11:40.6279621810 ./follower1/2/3
    2019-01-10+13:11:40.6279621810 ./follower1/2/dirnam with spaces
    2019-01-10+13:11:40.6279621810 ./follower1/2/name with spaces
    2019-01-10+13:11:56.5968732640 ./follower1/2/file
    2019-01-10+13:13:18.3975675510 ./follower2
    2019-01-10+13:13:19.4016254340 ./follower3
    2019-01-10+13:13:20.4056833250 ./follower4
    2019-01-10+13:13:21.4097412230 ./follower5
    2019-01-10+13:13:22.4137991260 ./follower6
    2019-01-10+13:13:23.4138568040 ./follower7
    2019-01-10+13:13:24.4219149500 ./follower8
    2019-01-10+13:13:25.4259728780 ./follower9
    2019-01-10+13:15:34.4094596830 ./leader1
    2019-01-10+13:15:36.8336011960 .
    2019-01-10+13:15:36.8336011960 ./leader2
    2019-01-10+13:25:03.0751878450 ./follower1/2
    

    igual a,

    $ find . -type d -name "follower*" -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs echo rm -r
    rm -r ./follower1 ./follower2 ./follower3 ./follower4 ./follower5 ./follower6 ./follower7 ./follower8
    

    Então follower9é excluído porque é o diretório mais novo follower(diretórios com nomes, que não começam com follower( leader1, leader2e 2não estão no jogo).

    Agora adicionamos o critério de tempo -mtime +14e fazemos outro 'dry run' para verificar se funciona como deveria, quando mudamos o diretório para onde existem followerdiretórios reais,

    find . -type d -name "follower*" -mtime +14 -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs echo rm -r
    

    Finalmente removemos echoe temos uma linha de comando que pode fazer o que queremos,

    find . -type d -name "follower*" -mtime +14 -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs rm -r
    

    • findno diretório atual, diretórios com nomes começando com follower, que não são modificados desde 14 dias atrás.
    • Depois de imprimir e classificar , o diretório head -n -1mais recente será excluídofollower .
    • Os carimbos de hora são cortados e aspas duplas são adicionadas no início e no final de cada nome de diretório.
    • Finalmente, o resultado é canalizado xargscomo parâmetros rm -rpara remover os diretórios que queremos remover.

    2. Shellscript

    Eu fiz uma segunda alternativa, (o shellscript) que usa

    @      seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
    

    Também tem duas opções,

    • -nfuncionamento a seco
    • -vverboso

    • Modifiquei o shellscript de acordo com o que o OP deseja: insira o padrão como um parâmetro entre aspas simples, por exemplo, 'seguidor *'.

    • Sugiro que o nome do shellscript seja prune-dirsporque agora é mais geral (não mais apenas prune-followerspara remover diretórios follower*).

    Recomenda-se executar o shellscript com ambas as opções na primeira vez para 'ver' o que você fará e, quando parecer correto, remova o -npara que o shellscript remova os diretórios antigos o suficiente para serem removidos. Então vamos chamá-lo prune-dirse torná-lo executável.

    #!/bin/bash
    
    # date        sign     comment
    # 2019-01-11  sudodus  version 1.1
    # 2019-01-11  sudodus  enter the pattern as a parameter
    # 2019-01-11  sudodus  add usage
    # 2019-01-14  sudodus  version 1.2
    # 2019-01-14  sudodus  check if any parameter to the command to be performed
    
    # Usage
    
    usage () {
     echo "Remove directories found via the pattern (older than 'datint')
    
     Usage:    $0 [options] <pattern>
    Examples: $0 'follower*'
              $0 -v -n 'follower*'  # 'verbose' and 'dry run'
    The 'single quotes' around the pattern are important to avoid that the shell expands
    the wild card (for example the star, '*') before it reaches the shellscript"
     exit
    }
    
    # Manage options and parameters
    
    verbose=false
    dryrun=false
    for i in in "$@"
    do
     if [ "$1" == "-v" ]
     then
      verbose=true
      shift
     elif [ "$1" == "-n" ]
     then
      dryrun=true
      shift
     fi
    done
    if [ $# -eq 1 ]
    then
     pattern="$1"
    else
     usage
    fi
    
    # Command to be performed on the selected directories
    
    cmd () {
     echo rm -r "$@"
    }
    
    # Pattern to search for and limit between directories to remove and keep
    
    #pattern='follower*'
    datint=14  # days
    
    tmpdir=$(mktemp -d)
    tmpfil1="$tmpdir"/fil1
    tmpfil2="$tmpdir"/fil2
    
    secint=$((60*60*24*datint))
    seclim=$(date '+%s')
    seclim=$((seclim - secint))
    printf "%s limit-in-seconds\n" $seclim > "$tmpfil1"
    
    if $verbose
    then
     echo "----------------- excluding newest match:"
     find . -type d -name "$pattern" -printf "%T@ %p\n" | sort |tail -n1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/'
    fi
    
    # exclude the newest match with 'head -n -1'
    
    find . -type d -name "$pattern" -printf "%T@ %p\n" | sort |head -n -1 >> "$tmpfil1"
    
    # put 'limit-in-seconds' in the correct place in the sorted list and remove the timestamps
    
    sort "$tmpfil1" | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' > "$tmpfil2"
    
    if $verbose
    then
     echo "----------------- listing matches with 'limit-in-seconds' in the sorted list:"
     cat "$tmpfil2"
     echo "-----------------"
    fi
    
    # create 'remove task' for the directories older than 'limit-in-seconds'
    
    params=
    while read filnam
    do
     if [ "${filnam/limit-in-seconds}" != "$filnam" ]
     then
      break
     else
      params="$params $filnam"
     fi
    done < "$tmpfil2"
    cmd $params > "$tmpfil1"
    cat  "$tmpfil1"
    
    if ! $dryrun && ! test -z "$params"
    then
     bash "$tmpfil1"
    fi
    rm -r $tmpdir
    
    • Altere o diretório atual para o diretório com os followersubdiretórios
    • crie o arquivoprune-dirs
    • torná-lo executável
    • e execute com as duas opções-v -n

      cd directory-with-subdirectories-to-be-pruned/
      nano prune-dirs  # copy and paste into the editor and save the file
      chmod +x prune-dirs
      ./prune-dirs -v -n
      

    Teste

    Eu testei prune-dirsem um diretório com os seguintes subdiretórios, como visto comfind

    $ find . -type d -printf "%T+ %p\n"|sort
    2018-12-01+02:03:04.0000000000 ./follower1234
    2018-12-02+03:04:05.0000000000 ./follower3456
    2018-12-03+04:05:06.0000000000 ./follower4567
    2018-12-04+05:06:07.0000000000 ./leader8765
    2018-12-05+06:07:08.0000000000 ./bystander6789
    2018-12-06+07:08:09.0000000000 ./follower with spaces old
    2019-01-09+10:11:12.0000000000 ./follower7890
    2019-01-10+11:12:13.0000000000 ./follower8901
    2019-01-10+13:15:34.4094596830 ./leader1
    2019-01-10+13:15:36.8336011960 ./leader2
    2019-01-10+14:08:36.2606738580 ./2
    2019-01-10+14:08:36.2606738580 ./2/follower with spaces
    2019-01-10+17:33:01.7615641290 ./follower with spaces new
    2019-01-10+19:47:19.6519169270 .
    

    Uso

    $ ./prune-dirs
    Remove directories found via the pattern (older than 'datint')
    
     Usage:    ./prune-dirs [options] <pattern>
    Examples: ./prune-dirs 'follower*'
              ./prune-dirs -v -n 'follower*'  # 'verbose' and 'dry run'
    The 'single quotes' around the pattern are important to avoid that the shell expands
    the wild card (for example the star, '*') before it reaches the shellscript
    

    Executar com -v -n(uma execução a seco detalhada)

    $ ./prune-dirs -v -n 'follower*'
    ----------------- excluding newest match:
    "./follower with spaces new"
    ----------------- listing matches with 'limit-in-seconds' in the sorted list:
    "./follower1234"
    "./follower3456"
    "./follower4567"
    "./follower with spaces old"
    "limit-in-seconds"
    "./follower7890"
    "./follower8901"
    "./2/follower with spaces"
    -----------------
    rm -r "./follower1234" "./follower3456" "./follower4567" "./follower with spaces old"
    

    Um teste detalhado com um padrão mais geral

    $ LANG=C ./prune-dirs -v -n '*er*'
    ----------------- excluding newest match:
    "./follower with spaces new"
    ----------------- listing matches with 'limit-in-seconds' in the sorted list:
    "./follower1234"
    "./follower3456"
    "./follower4567"
    "./leader8765"
    "./bystander6789"
    "./follower with spaces old"
    "limit-in-seconds"
    "./follower7890"
    "./follower8901"
    "./leader1"
    "./leader2"
    "./2/follower with spaces"
    -----------------
    rm -r "./follower1234" "./follower3456" "./follower4567" "./leader8765" "./bystander6789" "./follower with spaces old"
    

    Executar sem nenhuma opção (um caso real removendo diretórios)

    $ ./prune-dirs 'follower*'
    rm -r "./follower1234" "./follower3456" "./follower4567" "./follower with spaces old"
    

    Executar com -v'tentar novamente'

    $ LANG=C ./prune-dirs -v 'follower*'
    ----------------- excluding newest match:
    "./follower with spaces new"
    ----------------- listing matches with 'limit-in-seconds' in the sorted list:
    "limit-in-seconds"
    "./follower7890"
    "./follower8901"
    "./2/follower with spaces"
    -----------------
    rm -r
    

    O shellscript não lista nenhum diretório 'acima' "limit-in-seconds", e não há arquivos listados para a rm -rlinha de comando, então o trabalho já foi feito (que é o resultado correto). Mas se você executar o shellscript novamente vários dias depois, algum novo diretório pode ser encontrado 'acima' "limit-in-seconds" e ser removido.

    • 7
  2. Emilio Galarraga
    2019-01-11T03:15:50+08:002019-01-11T03:15:50+08:00

    Complementando a resposta do Rowan. Você pode alterar o ponto pelo caminho para os diretórios

    find . -type d -name follower* -mtime +14 -exec rm -rf {} +;
    
    • 5
  3. Stéphane Chazelas
    2019-01-11T09:22:02+08:002019-01-11T09:22:02+08:00

    With zsh:

    (){ n=$#; } follower<->(/)       # count the number of follower<n> dirs
    
    to_remove=(follower<->(/m+13om)) # assumes the dir list is not changed
                                     # since the previous command
    
    (($#to_remove < n)) || to_remove[1]=() # keep the youngest if they're
                                           # all over 2 weeks old
    
    
    
    echo rm -rf $to_remove
    

    (remove echo when happy)

    • <-> any sequence of decimal digits (a short form of <1-20> be without bound).
    • (){code} args: anonymous function which here stores its number of arguments in $n.
    • (/omm+13): glob qualifier
    • /: only select files of type directory (equivalent of find's -type d)
    • m+13: files whose age in whole days is strictly greater than 13 days, so files that are 14 days old or older (equivalent of find's -mtime +13).
    • om: order by modification time (like ls -t younger files first)

    Note that it's dangerous to rely on directory modification time. directories are modified when files are added, removed or renamed in them (or when they're touched). Since those directories are numbered, you may want to rely on that numbering instead, so replace om with nOn (numerically Order in reverse (capital O) by name).

    To have the pattern in a variable, replace follower<-> with $~pattern and set pattern='follower<->' or any other value.

    • 5
  4. rowan
    2019-01-11T02:52:41+08:002019-01-11T02:52:41+08:00

    No momento em que eu preciso deletar arquivos ou diretórios relacionados ao tempo, eu usaria find.

    Antes de excluir qualquer coisa, você pode executar o comando algumas vezes para ver se encontra tudo o que deseja.

    find . -type d -mtime +14
    # -type c, File is of type c: d  directory
    # -mtime n, File's data was last modified n*24 hours ago.
    

    Se corresponder a todos os seus critérios, você pode adicionar -exec rm -r {} +:

    find . -type d -mtime +14 -exec rm -r {} +
    

    A razão de estarmos usando -execaqui é porque -deletenão funcionará se o diretório não estiver vazio.

    Confira man findmais orientações.

    • 3
  5. fra-san
    2019-01-11T07:33:09+08:002019-01-11T07:33:09+08:00

    Algumas soluções:

    1. Baseado no GNU find:

    #!/bin/bash
    
    # The pattern has to be available to subshells
    export patt="$1"
    
    find . -maxdepth 1 -type d -name "${patt}*" -mtime +14 \
      -exec sh -c '[ "$(find . -maxdepth 1 -type d -name "${patt}*" -print0 |
        sort -z -V |
        tail -z -n 1 |
        tr -d "\0")" != "$1" ]' sh {} \; \
      -exec sh -c 'echo rm -r "$1"' sh {} \;
    

    O script deve ser invocado como:

    ./script name_pattern
    

    Como está, ele lhe dará uma corrida seca. Remova echona última -execação para permitir que ele realmente exclua os diretórios.

    Será:

    • Encontre todos os diretórios no diretório atual que foram modificados há mais de 14 dias (mas veja a nota -mtimeabaixo) e tenha um nome que comece com o valor de ${patt}; para cada:
    • Ensure (the first -exec) that the found directory is not the last one matching the name pattern, sorting in ascending version order (-V) (to have, for instance, follower100 placed after follower2); if the test ([) fails, find skips to the next cycle and does not perform the actions that follow;
    • Remove the found directory (the second -exec).

    Here I am assuming an equivalence between sorting your directories in lexicographical order by name and sorting them by modification date. This is ok if your latest directory is defined in terms of its name.
    If, instead, your latest directory is the one with the most recent modification time, we have to replace the first -exec ... in the above code with this one:

      -exec sh -c '[ "$(find . -maxdepth 1 -type d -name "${patt}*" -printf "%T@\n" |
        sed "s/\..*$//" |
        sort -n |
        tail -n 1)" != "$(stat -c "%Y" "$1")" ]' sh {} \; \
    

    Where with an inner find we find all the directories matching the name pattern, print the list of their modification times in seconds since Epoch, cut the fractional part away, sort, take the last one and check that it is not equal to that of the current result of the outer find.

    Note that, using this filter, if all the matching directories are older than 14 days and have all exactly the same modification time none of them is deleted.


    Notes:

    Limiting the search to the content of the current directory (-maxdepth 1) is not strictly required.

    You may want to tell sort how to order things, e.g. adding export LC_ALL=C at the beginning of the script (refer to this answer to 'What does "LC_ALL=C" do?' about the issues you may have when sorting, depending on your localization settings).

    Note that, using -mtime +14, files that have been modified between 14 and 15 days ago are skipped even if their modification time is technically older than 14*24 hours from now (refer to man find for details; specifically, the description of -atime n).

    It will work even when names contain spaces, newlines, uncommon and non-printable characters.

    Compatibility: the flip side is that it is not portable: some features used here, notably find's -maxdepth, -print0 and -printf, the stat command, the -V option to sort and the -z option to sort and tail (and I am possibly forgetting some more), are not specified in POSIX.

    2. Based on shell features

    #!/bin/sh
    
    patt="$1"                 # The name pattern
    test -z "$patt" && exit   # Caution: pattern must not be empty
    
    days=14     # How old has to be a directory to get deleted, in days?
    last=       # The youngest directory
    
    dirs=( "$patt"* )     # Array of files matched by name (note, here we
                          # have everything that matches, not just dirs)
    now="$(date +'%s')"   # Now in seconds since Epoch
    
    threshold="$(( "$now" - ( "$days" * 24 * 60 *60 ) ))"
                          # Dirs older than this date (in seconds since
                          # Epoch) are candidates for deletion
    
    # We find the youngest directory in the array
    #
    for i in "${!dirs[@]}"; do
      if  [ -z "$last" ] ||
        ( [ -d "${dirs[$i]}" ] &&
          [ "$(stat -c '%Y' -- "${dirs[$i]}")" -gt "$(stat -c '%Y' -- "$last")" ] ); then
        last="${dirs[$i]}"
      fi
    done
    
    # We delete all the directories in the array that are
    # not the youngest one AND are older that the thrashold
    #
    for i in "${!dirs[@]}"; do
      if  [ -d "${dirs[$i]}" ] &&
          [ "${dirs[$i]}" != "$last" ] &&
          [ "$(stat -c '%Y' -- "${dirs[$i]}")" -lt "$threshold" ]; then
        echo rm -rf -- "${dirs[$i]}"
      fi
    done
    

    This script, too, is meant to be invoked as

    ./script name_pattern
    

    Again, it will give you a dry run until you remove echo from echo rm -rf -- "${dirs[$i]}".

    It will:

    • Populate an array with the names of all files, in the current directory, that match the name pattern;
    • Determine the youngest directory in the array;
    • Delete all the directories in the array that 1) are older than 14 days AND 2) are not the youngest one.

    Notes:

    It will target directories older then 14 days from now (unlike find). Thus, these two solutions are not strictly equivalent.
    Also, if all the matching directories are older than the threshold and have all the same modification time, it will delete all but one of them - randomly chosen.

    Names with uncommon characters are ok, including newlines and non printable ones.

    Compatibility: even this solution relies on some non POSIX features: namely, stat and the %s date format. Ah, and arrays, apparently...

    • 2

relate perguntas

  • Subtraindo a mesma coluna entre duas linhas no awk

  • Um script que imprime as linhas de um arquivo com seu comprimento [fechado]

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Dividir por delimitador e concatenar problema de string

  • MySQL Select com função IN () com array bash

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve